Home > Blockchain >  XSLT - Different context of the FOR extract the value
XSLT - Different context of the FOR extract the value

Time:09-03

I need some hits about different context with check of text to extract the correct value.

I already did for inside for but no works proper.

The XML below:

<?xml version="1.0" encoding="UTF-8"?>
<ORDERS05>
    <IDOC BEGIN="1">
        <E1EDP01 SEGMENT="1">
            <E1EDP05 SEGMENT="1">
                <KOTXT>Total item price</KOTXT>
                <KRATE>20.55</KRATE>
            </E1EDP05>
        </E1EDP01>
        <E1EDP01 SEGMENT="1">
            <E1EDP05 SEGMENT="1">
                <KOTXT>Total item price</KOTXT>
                <KRATE>8.03</KRATE>
            </E1EDP05>
        </E1EDP01>
        <E1EDP01 SEGMENT="1">
            <E1EDP05 SEGMENT="1">
                <KOTXT>Total item price</KOTXT>
                <KRATE>99999999</KRATE>
            </E1EDP05>
            <E1EDP05 SEGMENT="1">
                <KOTXT>Total net price</KOTXT>
                <KRATE>9.80</KRATE>
            </E1EDP05>
        </E1EDP01>
        <E1EDP01 SEGMENT="1">
            <E1EDP05 SEGMENT="1">
                <KOTXT>Total item price</KOTXT>
                <KRATE>100000</KRATE>
            </E1EDP05> 
        </E1EDP01>
        <E1EDP01 SEGMENT="1"> 
            <E1EDP05 SEGMENT="1">
                <KOTXT>Total item price</KOTXT>
                <KRATE>10.32</KRATE>
            </E1EDP05>
            <E1EDP05 SEGMENT="1">
                <ALCKZ>-</ALCKZ>
                <KOTXT>Discount</KOTXT>
            </E1EDP05>
            <E1EDP05 SEGMENT="1">
                <KOTXT>Total net price</KOTXT>
                <KRATE>9.80</KRATE>
            </E1EDP05>      
        </E1EDP01>
    </IDOC>
</ORDERS05>

Basically the rules is, in the children node E1EDP05 if the tag KOTXT contains 'Total item price' extract the value from KRATE.

XSLT:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:strip-space elements="*"/>
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
   <xsl:template match="/">
      <request>
         <import>
            <fields>
               <xsl:for-each select="//E1EDP01">
                  <Line>
                    <UnitPriceGross fid="7053">
                         <xsl:value-of select="//E1EDP05[KOTXT='Total item price']/KRATE"/>
                     </UnitPriceGross>
                  </Line>
               </xsl:for-each>
            </fields>
         </import>
      </request>
   </xsl:template>
</xsl:stylesheet>

Current result:

<?xml version="1.0" encoding="UTF-8"?>
<request>
   <import>
      <fields>
         <Line>
            <UnitPriceGross fid="7053">20.55</UnitPriceGross>
         </Line>
         <Line>
            <UnitPriceGross fid="7053">20.55</UnitPriceGross>
         </Line>
         <Line>
            <UnitPriceGross fid="7053">20.55</UnitPriceGross>
         </Line>
         <Line>
            <UnitPriceGross fid="7053">20.55</UnitPriceGross>
         </Line>
         <Line>
            <UnitPriceGross fid="7053">20.55</UnitPriceGross>
         </Line>
      </fields>
   </import>
</request>

The correct result should be with accordioning values not only for the first KRATE as (20.55)

Correct Result:

<?xml version="1.0" encoding="UTF-8"?>
<request>
   <import>
      <fields>
         <Line>
            <UnitPriceGross fid="7053">20.55</UnitPriceGross>
         </Line>
         <Line>
            <UnitPriceGross fid="7053">8.03</UnitPriceGross>
         </Line>
         <Line>
            <UnitPriceGross fid="7053">99999999</UnitPriceGross>
         </Line>
         <Line>
            <UnitPriceGross fid="7053">100000</UnitPriceGross>
         </Line>
         <Line>
            <UnitPriceGross fid="7053">10.32</UnitPriceGross>
         </Line>
      </fields>
   </import>
</request>

Thank you for any idea.

Kind regards,

CodePudding user response:

You are using an incorrect XPath selector insinde xsl:value-of: there you want to match E1EDP05 elements descendant of the currently iterated E1EDP01 context node, but the // operator used like that matches every E1EDP05 descendant of the document root.

You should change it by explicitly adding the context node to make it relative, like this:

.//E1EDP05[KOTXT='Total item price']/KRATE

See the complete result: http://xsltransform.net/bEzknsQ

See also:
https://www.w3.org/TR/xpath-10/#path-abbrev:~:text=//para selects all the para descendants of the document root and thus selects all para elements in the same document as the context node
https://www.w3.org/TR/xpath-10/#path-abbrev:~:text=.//para selects the para element descendants of the context node

  • Related