cancel
Showing results for 
Search instead for 
Did you mean: 

Error in Muenchian method in XSLT mapping using sapxmltoolkit.jar

Doug_Munford
Participant
0 Kudos

Hi,

The following example produces a different result in SAP from that of Altova, Microsoft providers. It is a resonably complex Muenchian transformation that I have reduced this to the core issue:

Have tried with SP14 but same result on every delivered version of sapxmltoolit.jar

I am trying to extract a unique set of locationCodes to assemble an IDOC for each locationCode - breaking out the relevant order lines.

<b>My question is twofold:</b>

a) is the behaviour of sapxmltoolkit errannt to the spec?

b) is there another way to produce this list or work around?


<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="xml" version="1.0" indent="yes"/>
  <xsl:key name="partner-ids" match="PRODQNTY/LOCNQNTY" use="locationCode"/>
  <xsl:template name="buildIdoc" match="ORDER">
    <ORDERS05>
      <xsl:for-each select="PRODQNTY/LOCNQNTY[count(.|key('partner-ids',locationCode)[1])=1]">
        <xsl:sort select="locationCode" data-type="number"/>
        <xsl:comment><xsl:value-of select="locationCode"/> Location Code</xsl:comment>
        <xsl:comment><xsl:value-of select="../lineNo"/> Line Number</xsl:comment>
        <IDOC BEGIN="1"></IDOC>
      </xsl:for-each>
    </ORDERS05>
  </xsl:template>
</xsl:stylesheet>

<b>Sample input document:</b>


?xml version="1.0"?>
<ORDER loops-id="ORDER">
  <PRODQNTY loops-id="PRODQNTY">
    <lineNo>1</lineNo>
    <productCode>9990007454</productCode>
    <LOCNQNTY>
      <locationCode>001</locationCode>
      <quantityOrdered>6</quantityOrdered>
    </LOCNQNTY>
    <LOCNQNTY>
      <locationCode>004</locationCode>
      <quantityOrdered>3</quantityOrdered>
    </LOCNQNTY>
    <LOCNQNTY>
      <locationCode>005</locationCode>
      <quantityOrdered>2</quantityOrdered>
    </LOCNQNTY>
    <LOCNQNTY>
      <locationCode>006</locationCode>
      <quantityOrdered>1</quantityOrdered>
    </LOCNQNTY>
    <LOCNQNTY>
      <locationCode>007</locationCode>
      <quantityOrdered>1</quantityOrdered>
    </LOCNQNTY>
    <LOCNQNTY>
      <locationCode>009</locationCode>
      <quantityOrdered>3</quantityOrdered>
    </LOCNQNTY>
    <LOCNQNTY>
      <locationCode>021</locationCode>
      <quantityOrdered>1</quantityOrdered>
    </LOCNQNTY>
    <LOCNQNTY>
      <locationCode>082</locationCode>
      <quantityOrdered>2</quantityOrdered>
    </LOCNQNTY>
    <unDefData></unDefData>
    <segmentCount>0</segmentCount>
  </PRODQNTY>
  <PRODQNTY loops-id="PRODQNTY">
    <lineNo>2</lineNo>
    <productCode>1864503696</productCode>
    <LOCNQNTY>
      <locationCode>001</locationCode>
      <quantityOrdered>4</quantityOrdered>
    </LOCNQNTY>
    <LOCNQNTY>
      <locationCode>004</locationCode>
      <quantityOrdered>2</quantityOrdered>
    </LOCNQNTY>
    <LOCNQNTY>
      <locationCode>005</locationCode>
      <quantityOrdered>2</quantityOrdered>
    </LOCNQNTY>
    <LOCNQNTY>
      <locationCode>006</locationCode>
      <quantityOrdered>1</quantityOrdered>
    </LOCNQNTY>
    <LOCNQNTY>
      <locationCode>007</locationCode>
      <quantityOrdered>1</quantityOrdered>
    </LOCNQNTY>
    <LOCNQNTY>
      <locationCode>009</locationCode>
      <quantityOrdered>1</quantityOrdered>
    </LOCNQNTY>
    <LOCNQNTY>
      <locationCode>021</locationCode>
      <quantityOrdered>1</quantityOrdered>
    </LOCNQNTY>
    <LOCNQNTY>
      <locationCode>082</locationCode>
      <quantityOrdered>1</quantityOrdered>
    </LOCNQNTY>
  </PRODQNTY>
</ORDER>

<b>Expected Output:</b> - from Altova - 1 record per locationCode



<?xml version="1.0" encoding="UTF-8"?>
<ORDERS05>
	<!--001 Location Code-->
	<!--1 Line Number-->
	<IDOC BEGIN="1" />
	<!--004 Location Code-->
	<!--1 Line Number-->
	<IDOC BEGIN="1" />
	<!--005 Location Code-->
	<!--1 Line Number-->
	<IDOC BEGIN="1" />
	<!--006 Location Code-->
	<!--1 Line Number-->
	<IDOC BEGIN="1" />
	<!--007 Location Code-->
	<!--1 Line Number-->
	<IDOC BEGIN="1" />
	<!--009 Location Code-->
	<!--1 Line Number-->
	<IDOC BEGIN="1" />
	<!--021 Location Code-->
	<!--1 Line Number-->
	<IDOC BEGIN="1" />
	<!--082 Location Code-->
	<!--1 Line Number-->
	<IDOC BEGIN="1" />
</ORDERS05>

<b>Output from sapxmltoolkit.jar</b> - 1 record per locationCode per PRODQNTY line so I get a non unique set of locationCodes: (every location twice in this example - and with 16 order lines, every location 16 times and 128 IDOCs (instead of 8 IDOCs).


<?xml version="1.0" encoding="utf-8"?>
<ORDERS05>
  <!--001 Location Code-->
  <!--1 Line Number-->
  <IDOC BEGIN="1"/>
  <!--001 Location Code-->
  <!--2 Line Number-->
  <IDOC BEGIN="1"/>
  <!--004 Location Code-->
  <!--1 Line Number-->
  <IDOC BEGIN="1"/>
  <!--004 Location Code-->
  <!--2 Line Number-->
  <IDOC BEGIN="1"/>
  <!--005 Location Code-->
  <!--1 Line Number-->
  <IDOC BEGIN="1"/>
  <!--005 Location Code-->
  <!--2 Line Number-->
  <IDOC BEGIN="1"/>
  <!--006 Location Code-->
  <!--1 Line Number-->
  <IDOC BEGIN="1"/>
  <!--006 Location Code-->
  <!--2 Line Number-->
  <IDOC BEGIN="1"/>
  <!--007 Location Code-->
  <!--1 Line Number-->
  <IDOC BEGIN="1"/>
  <!--007 Location Code-->
  <!--2 Line Number-->
  <IDOC BEGIN="1"/>
  <!--009 Location Code-->
  <!--1 Line Number-->
  <IDOC BEGIN="1"/>
  <!--009 Location Code-->
  <!--2 Line Number-->
  <IDOC BEGIN="1"/>
  <!--021 Location Code-->
  <!--1 Line Number-->
  <IDOC BEGIN="1"/>
  <!--021 Location Code-->
  <!--2 Line Number-->
  <IDOC BEGIN="1"/>
  <!--082 Location Code-->
  <!--1 Line Number-->
  <IDOC BEGIN="1"/>
  <!--082 Location Code-->
  <!--2 Line Number-->
  <IDOC BEGIN="1"/>
</ORDERS05>

Accepted Solutions (0)

Answers (1)

Answers (1)

Doug_Munford
Participant
0 Kudos

A bit more heartache & trials and I solved it

The key defition is unstable in XSLT the way I defined it

Simple change to the XSLT: remove the PRODQNTY node reference from the match attribute:

<b>incorrect key:</b>


<xsl:key name="partner-ids" match="PRODQNTY/LOCNQNTY" use="locationCode"/>

<b>correct key:</b>


<xsl:key name="partner-ids" match="LOCNQNTY" use="locationCode"/>

And the "group-by or Muenchian method" loop statement:


<xsl:for-each select="PRODQNTY/LOCNQNTY[count(.|key('partner-ids',locationCode)[1])=1]">

Hopes this helps someone else....

Regds Doug.