Skip to Content
Author's profile photo Tobias Trapp

SmartForm Generation Using Advanced ABAP XSLT Techniques

In my blog entry Output Management in the Large and the Usage of Generic XSF Containers I discussed a scenario where output is generated by a third party outputmanagement system (OMS tool) that generates PDF from XSF documents created by SAP SmartForms. Therefore we need use XSF only a generic data container, the layout is defined within the OMS tool.

Within this scenario let’s consider the case that you have to create a great number of SmartForms that are almost similar. The usual way is that you create a set of SmartForms by copying a master SmartForm and changing the interface as well as the content of each copied SmartForm. Later we have to test the copied SmartForm. If the interface of the SmartForm changes we have to change the SmartForm and do the testing again. The Creation of many SmartForms this can be very time consuming so you might consider automatization.

SmartForm generation is quite easy using XML technologies. In transaction SMARTFORMS you can up- and download SmartForms as XML documents. Here is an example:

<?xml version="1.0" encoding="utf-8"?>
<sf:SMARTFORM xmlns:sf="urn:sap-com:SmartForms:2000:internal-structure"
xmlns="urn:sap-com:sdixml-ifr:2000" sf:language="DE">


Often Creation by Manipulation is Better than Creation from the Scratch

SmartForms generation seems to be quite straight forward. Nevertheless SmartForms are quite complicated artefacts, think of ABAP code in GCODING elements. But how complex is a SmartForm I want to generate? To get an overview I use a little piece of XSLT folklore:

<xsl:transform version="1.0" mlns:xsl="">
  <xsl:output method="text" version="1.0" encoding="UTF-8" indent="yes"/>
  <xsl:variable name="newline"><xsl:text> </xsl:text></xsl:variable>
  <xsl:key use="name()" name="elements" match="*"/>
  <xsl:template match="/">
    <xsl:for-each select="//*[generate-id(.)=generate-id(key('elements', name())[1])]">
      <xsl:sort elect="name()"/>
      <xsl:for-each select="key('elements', name())">
      <xsl:if test="position()=1">
        <xsl:text>For element /xsl:text>
        <xsl:value-of select="name()"/>
        <xsl:text> there are /xsl:text>
        <xsl:value-of select="count(//*[name()=name(current())])"/>
        <xsl:text> occurrences.</xsl:text>
        <xsl:value-of select="$newline"/>
    <xsl:value-of select="$newline"/> 
    <xsl:text>Total occurrences:</xsl:text>
    <xsl:value-of select="count(//*)"/>

If I apply this transformation to my SmartForm master document in XML representation it says that there are 138 different element types in 2417 elements. This is quite too much. Every time you want to generate more complicated artefacts I recommend to manipulate them from a sample document. Obviously within the new SmartForm follwing following elements have to be changed:

  • FORMNAME – the name of the SmartForm
  • DEVCLASS – the name of the package
  • TYPENAME – the DDIC type of the generic part to be given out

To create a new SmartForm you will have to do more: You will have add additional XML subtrees for the generic data type to be given out and please don’t forget the REFFIELDS elements that you’ll need for currency units.

XML Generation Techniques – Passing Node Sets to XSL Transformations

If I am doing XML generation I prefer an eclectic approach. XSLT is the right tool for copying parts of the sample document, for projections and renaming of text nodes. But for SmartForm generation I need a lot of application logic like RTTI functions. Of course I can use ABAP method calls within the XSL transformation but usually I try not to put too much application logic into an XSL transformation.

Therefore I use different techniques like Simple Transformations and good old iXML Library to create sets of XML elements as IF_IXML_NODE_COLLECTION. These node sets can be passed as parameters to an XSL transformation using as PARAMETER of the CALL TRANSFORMATION command. Within the transformation the node set parameters are bound to a variable and can be given out to the output document perhaps using xsl:copy-of command. In fact we can even manipulate the content of a variable because the ABAP XSLT processor has no result fragment tree and can deal with node sets as temporary trees like I discussed in XML Processing in ABAP – Part 7: The Power of XSLT 2.0. But usually copying of node sets to the result document suffices for my purposes.


This blog entry covered following topics:

  • SAP SmartForms can be up- and downloaded as XML documents. This makes it possible to generate them. Up- and downloading can be integrated into the generation process: Please study the SAPlink plugin for SmartForms to see how it works. By the way, this plugin can be further improved because the XML document is not readable. I suggest to copy the subtree of the SMARTFORM element into the nugget.
  • Generative techniques are quite powerful but often describing the wanted result properly is quite difficult and needs too much effort. That’s why I prefer manipulation as generation technique.
  • In my opinion manipulation is a superior generation technique. I used it once to generate test cases in a data exchange scenario using a manipulation language. This leads to model driven testing and perhaps I will write another blog entry about it.
  • You can use ABAP XSLT for generation of SAP SmartForms. I recommend not to put too much logic into the XSLT program. I think it is better to generate subtrees of XML elements and pass them to the XSL transformation. This will leadto a proper and flexible modularization.

Assigned Tags

      Be the first to leave a comment
      You must be Logged on to comment or reply to a post.