cancel
Showing results for 
Search instead for 
Did you mean: 

XSL

Former Member
0 Kudos

Hi

I am trying to use an xslt stylesheet to sort my idoc segments but cannot get it to work. I am not getting any errors and I am getting an output but the sorting is not happening.

Here is my code

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
   <xsl:template match="/ANYIDOC/IDOC">
      <ns1:ANYIDOC xmlns:ns1="urn:sap-com:document:sap:idoc:messages">
        
            <ns1:IDOC>
	<xsl:for-each select=".">
	<xsl:sort select="SEG1/FIELD1"/>
               	<xsl:copy-of select="SEG1"/>
	</xsl:for-each>
            </ns1:IDOC>
        

      </ns1:ANYIDOC>
   </xsl:template>
</xsl:stylesheet>

As you can see I am trying to sort the SEG1 segments using the FIELD1 field within the SEG1 segment.

I hope you can help.

Accepted Solutions (1)

Accepted Solutions (1)

Former Member
0 Kudos

Hi,

Sorry no joy yet.... Could anybody please suggest a way to make this sort function work please?

Thanks

SA

Former Member
0 Kudos

Hi SA,

node() is working for me. Did you tried that part??

regards

Ramesh

Former Member
0 Kudos

Hi Ramesh,

Now sorry it doesn't seem to be. This is the exact code that I have

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
   <xsl:template match="/ORDERS05/IDOC">
      <ns1:ORDERS05 xmlns:ns1="urn:sap-com:document:sap:idoc:messages">
         <ns1:IDOC>
            <xsl:for-each select=".">
               <xsl:sort select="E1EPD01/POSEX"/>
               <xsl:copy-of select="node()"/>
            </xsl:for-each>
         </ns1:IDOC>
      </ns1:ORDERS05>
   </xsl:template>
</xsl:stylesheet>

And this is the input. I want to get an out put where all qualifier ones come first and then the qualifiers twos come second and so on... could you please let me know what you feel could be the problem?

<?xml version="1.0" encoding="UTF-8"?>
<ORDERS05>
   <IDOC BEGIN="">
      <E1EDK01>
         <ACTION>HeaderField1</ACTION>
         <KZABS>HedaerField2</KZABS>
      </E1EDK01>
      <E1EDP01 SEGMENT="">
         <POSEX>Qualifier1</POSEX>
         <ACTION>A</ACTION>
         <E1EDP02>
            <QUALF>E1EDP02.A.1</QUALF>
            <BELNR>E1EDP02.AQ.1</BELNR>
         </E1EDP02>
         <E1EDPAD>
            <QUALF>E1EDPAD.A.1</QUALF>
            <ICC>E1EDPAD.AQ.1</ICC>
            <E1TXTH1>
               <FUNCTION>E1TXTH1.A.2</FUNCTION>
               <TDOBJECT>E1TXTH1.AQ.2</TDOBJECT>
               <E1TXTP1>
                  <TDFORMAT>E1TXTP1.A.2.1</TDFORMAT>
                  <TDLINE>E1TXTP1.AQ.2.1</TDLINE>
               </E1TXTP1>
               <E1TXTP1>
                  <TDFORMAT>E1TXTP1.A.2.2</TDFORMAT>
                  <TDLINE>E1TXTP1.AQ.2.2</TDLINE>
               </E1TXTP1>
            </E1TXTH1>
         </E1EDPAD>
      </E1EDP01>
      <E1EDP01 SEGMENT="">
         <POSEX>Qualifier2</POSEX>
         <ACTION>B</ACTION>
         <E1EDP02>
            <QUALF>E1EDP02.B.1</QUALF>
            <BELNR>E1EDP02.BQ.1</BELNR>
         </E1EDP02>
         <E1EDPAD>
            <QUALF>E1EDPAD.B.1</QUALF>
            <ICC>E1EDPAD.BQ.1</ICC>
            <E1TXTH1>
               <FUNCTION>E1TXTH1.B.2</FUNCTION>
               <TDOBJECT>E1TXTH1.BQ.2</TDOBJECT>
               <E1TXTP1>
                  <TDFORMAT>E1TXTP1.B.2.1</TDFORMAT>
                  <TDLINE>E1TXTP1.BQ.2.1</TDLINE>
               </E1TXTP1>
               <E1TXTP1>
                  <TDFORMAT>E1TXTP1.B.2.2</TDFORMAT>
                  <TDLINE>E1TXTP1.BQ.2.2</TDLINE>
               </E1TXTP1>
            </E1TXTH1>
         </E1EDPAD>
         <E1EDPAD>
            <QUALF>E1EDPAD.B.1</QUALF>
            <ICC>E1EDPAD.BQ.1</ICC>
         </E1EDPAD>
      </E1EDP01>
      <E1EDP01 SEGMENT="">
         <POSEX>Qualifier1</POSEX>
         <ACTION>AA</ACTION>
         <E1EDP02>
            <QUALF>E1EDP02.AA.1</QUALF>
            <BELNR>E1EDP02.AAQ.1</BELNR>
         </E1EDP02>
         <E1EDPAD>
            <QUALF>E1EDPAD.AA.1</QUALF>
            <ICC>E1EDPAD.AAQ.1</ICC>
            <E1TXTH1>
               <FUNCTION>E1TXTH1.AA.2</FUNCTION>
               <TDOBJECT>E1TXTH1.AAQ.2</TDOBJECT>
               <E1TXTP1>
                  <TDFORMAT>E1TXTP1.AA.2.1</TDFORMAT>
                  <TDLINE>E1TXTP1.AAQ.2.1</TDLINE>
               </E1TXTP1>
               <E1TXTP1>
                  <TDFORMAT>E1TXTP1.AA.2.2</TDFORMAT>
                  <TDLINE>E1TXTP1.AAQ.2.2</TDLINE>
               </E1TXTP1>
            </E1TXTH1>
         </E1EDPAD>
      </E1EDP01>
   </IDOC>
</ORDERS05>

Former Member
0 Kudos

Hi SA,

Try this, it will work

<?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" encoding="utf-8" omit-xml-declaration="yes"/>
   <xsl:template match="/ORDERS05/IDOC">
     <ns1:ORDERS05 xmlns:ns1="urn:sap-com:document:sap:idoc:messages">
         <ns1:IDOC>
            <xsl:for-each select="//E1EDP01">
                        <xsl:sort select="POSEX"/>
			<xsl:copy-of select="current()"/>
            </xsl:for-each>
         </ns1:IDOC>
      </ns1:ORDERS05>
   </xsl:template>

  </xsl:stylesheet>

regards

Ramesh

Former Member
0 Kudos

Ramesh you legend!

It works... Could you please let me know what the issue was?

Thanks

peter_wallner2
Active Contributor
0 Kudos

Hi SeegingAnswers,

I would not use xsl:for-each. I made the experience that it is not reliable when dealing with big amounts of data.

I came up with this, using an Identity Transform:


<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:output indent="yes"/>
    
    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()">
                <xsl:sort select="POSEX"/>
            </xsl:apply-templates>
        </xsl:copy>
    </xsl:template>
 
</xsl:stylesheet>

best regards,

Peter

Former Member
0 Kudos

Thanks SA.

Good that your issue got solved.

We were using wrong function to get the node contents. We should have used current() which is the function returns a node-set that contains only the current node.

Peter's code is good though. I would recommend it.

@Peter: Thanks for sharing, i updated with your knowledge piece.

Regards

Ramesh

Answers (4)

Answers (4)

Former Member
0 Kudos

Thank you Peter...

So you are saying that your version would be more performant?

Sorry I ran out of 6 points to give so only assigned 2... I will assign more if it allows me on your reply.

peter_wallner2
Active Contributor
0 Kudos

Hello SeekingAnswers,

Don't worry about points. Yes, I did make the experience that xsl:apply-templates was more performant and reliable than xsl:for-each. I was also dealing with an XML file of some thousand lines.

It is up to you. In case you run into issues with the for-each-solution you can always use mine. For XSLT questions I can recommend http://stackoverflow.com.

Best regards,

Peter

Former Member
0 Kudos

Thank you very much Peter for your input and link!

Former Member
0 Kudos
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
   <xsl:template match="/ANYIDOC/IDOC">
      <ns1:ANYIDOC xmlns:ns1="urn:sap-com:document:sap:idoc:messages">
        
            <ns1:IDOC>
	<xsl:for-each select=".">
	<xsl:sort select="SEG1/FIELD1"/>
	<xsl:copy-of select="node()"/>
	</xsl:for-each>
            </ns1:IDOC>
        
 
      </ns1:ANYIDOC>
   </xsl:template>
</xsl:stylesheet>

Try node() function as explained above

Try the above changes

Edited by: Ramesh P on Sep 12, 2011 10:13 PM

Former Member
0 Kudos

Hi,

Even i tried in XML Spy, i am also getting blank.

But for temporary solution you can use

<xsl:value-of select="">

for each element. This is working for me.

Let me see if copy works, i will let you know.

regards

Ramesh

Former Member
0 Kudos

Hi Ramesh,

Would you mind posting the entire code solution you are using as I am still unable to get this to work.

I am now using the following and it is the sort tag that causes it to give nothing... when yo take it away you get the result but not sorted...

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">


 <xsl:template match="/ANYIDOC/IDOC">
      <ns1:ANYIDOC xmlns:ns1="urn:sap-com:document:sap:idoc:messages">
               <xsl:for-each select=".">
<xsl:sort select="/SEG1/FIELD1">
<ns1:IDOC>
                  <xsl:copy-of select="SEG1"/>
               </ns1:IDOC>
</xsl:sort>
</xsl:for-each>

      </ns1:ANYIDOC>
   </xsl:template>



</xsl:stylesheet>

baskar_gopalakrishnan2
Active Contributor
0 Kudos