02-15-2017 8:25 AM
Hey everyone,
after my last approach of working with SAP Simple Transformations (https://answers.sap.com/questions/124003/manipulating-incoming-json-with-simple-transformat.html) I'm now working with an incoming XML and a XSLT Transformation. It should use the input XML and transform it into a SAP structure.
My XML (shortened example):
<result>
<row>
<idSite>3</idSite>
<idVisit>5474057</idVisit>
<actionDetails>
<row>
<type>goal</type>
<goalId>2</goalId>
<revenue>0</revenue>
<goalPageId>45316491</goalPageId>
<serverTimePretty>Feb 12, 2017 23:55:14</serverTimePretty>
<timestamp>1486943714</timestamp>
</row>
...
</actionDetails>
<searches>0</searches>
<actions>24</actions>
</row>
...
</result>
My XSLT (also shortened, but the problem is shown):
<xsl:transform version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:sap="http://www.sap.com/sapxsl">
<xsl:strip-space elements="*"/>
<xsl:template match="/">
<asx:abap xmlns:asx="http://www.sap.com/abapxml" version="1.0">
<asx:values>
<RESULT>
<xsl:for-each select="result/row">
<VISIT>
<SERVERDATE> <xsl:value-of select="serverDate"/> </SERVERDATE>
<USERID> <xsl:value-of select="userId"/> </USERID>
<VISITORTYPE><xsl:value-of select="visitorType"/> </VISITORTYPE>
<SEARCHES> <xsl:value-of select="searches"/> </SEARCHES>
<ACTIONS> <xsl:value-of select="actions"/> </ACTIONS>
<xsl:for-each select="actionDetails">
<xsl:variable name="row" select="row" />
<ACTIONDETAILS>
<TYPE> <xsl:value-of select="$row/type"/> </TYPE>
<URL> <xsl:value-of select="$row/url"/> </URL>
<GOALNAME><xsl:value-of select="$row/goalName"/></GOALNAME>
<ITEMS> <xsl:value-of select="$row/items"/> </ITEMS>
<xsl:for-each select="itemDetails/row">
<ITEMDETAILS>
<ITEMSKU> <xsl:value-of select="itemSKU"/></ITEMSKU>
<ITEMNAME><xsl:value-of select="itemName"/></ITEMNAME>
</ITEMDETAILS>
</xsl:for-each>
</ACTIONDETAILS>
</xsl:for-each>
<RESULT> <xsl:value-of select="result"/> </RESULT>
<MESSAGE> <xsl:value-of select="message"/> </MESSAGE>
</VISIT>
</xsl:for-each>
</RESULT>
</asx:values>
</asx:abap>
</xsl:template>
</xsl:transform>
Problem: Once it reaches the first xsl:value-of inside of the inner for-each (at TYPE), it crashes and the debugger throws an CX_XSLT_FORMAT_ERROR. Without debugging it just says "Unexpected text for XML-ABAP transformation."
When I validate my files with an online XSLT Validator (http://www.freeformatter.com/xsl-transformer.html), it does work fine.
Now my assumption/question: Are there some SAP-specific rules for XSLT or XPath I need to follow? I would say so, because it works outside of SAP. I tried to find any solution for this, but without success.
Thanks in advance and kind regards
02-17-2017 7:21 AM
Got it:
...
<ACTIONDETAILS>
<xsl:for-each select="actionDetails/row">
<ACTIONDETAIL>
<TYPE> <xsl:value-of select="type"/> </TYPE>
...
</ACTIONDETAIL>
</xsl:for-each>
</ACTIONDETAILS>
For creating data for an internal table, I needed a parent node <ACTIONDETAILS> to add a collection of child elements <ACTIONDETAIL>.
I still can't explain though why it validated in both an online validator and the XSLT tester in SAP.
02-17-2017 7:21 AM
Got it:
...
<ACTIONDETAILS>
<xsl:for-each select="actionDetails/row">
<ACTIONDETAIL>
<TYPE> <xsl:value-of select="type"/> </TYPE>
...
</ACTIONDETAIL>
</xsl:for-each>
</ACTIONDETAILS>
For creating data for an internal table, I needed a parent node <ACTIONDETAILS> to add a collection of child elements <ACTIONDETAIL>.
I still can't explain though why it validated in both an online validator and the XSLT tester in SAP.
01-02-2018 5:01 PM
Please close the question.
PS: from the XML point of view, it's not an error to not have <ACTIONDETAILS>. But you must have it because of ABAP, containing the name of the internal table (by the way you didn't show the description of your target ABAP variable): <ITABNAME><xsl:for-each ...><item>...</item></xsl-for-each></ITABNAME> (name "item" may vary depending on the rule explained in asXML - Mapping of Internal Tables).