Search code examples
xmlxsltxslt-2.0

How to fetch the each element value as per the order of the plancode


I need table row should fetch as per the order of the Code value

Input xml I'm having:

<Group>
    <Maps>
        <Map>
            <Code>20000</Code>
        </Map>
        <Map>
            <Code>30000</Code>
        </Map>
        <Map>
            <Code>40000</Code>
        </Map>
        <Map>
            <Code>50000</Code>
        </Map>
    </Maps>
    <Details>
        <Detail>
            <Code>40000</Code>
            <Description>Variable</Description>
        </Detail>
        <Detail>
            <Code>50000</Code>
            <Description>Non-Variable</Description>
        </Detail>
        <Detail>
            <Code>30000</Code>
            <Description>Benefit</Description>
        </Detail>
        <Detail>
            <Code>20000</Code>
            <Description>Non-Benefit</Description>
        </Detail>
    </Details>
</Group>

XSL I have tried the below using the variable:

<xsl:template match="Group">
      <xsl:variable name="MapCode" select="Maps/Map/Code"/>
      <row>
         <entry>Code</entry>
         <xsl:for-each select="Maps/Map">
            <entry>
               <p>
                  <xsl:value-of select="Code"/>
               </p>
            </entry>
         </xsl:for-each>
      </row>
      <row>
         <entry>Level</entry>
         <xsl:for-each select="Details/Detail[Code=$MapCode]">
            <entry>
               <p>
                  <xsl:value-of select="Description"/>
               </p>
            </entry>
         </xsl:for-each>
      </row>
      </xsl:template>

Actual Output I'm getting:

     <row>
      <entry>Code</entry>
      <entry>
         <p>20000</p>
      </entry>
      <entry>
         <p>30000</p>
      </entry>
      <entry>
         <p>40000</p>
      </entry>
      <entry>
         <p>50000</p>
      </entry>
   </row>
   <row>
      <entry>Level</entry>
      <entry>
         <p>Variable</p>
      </entry>
      <entry>
         <p>Non-Variable</p>
      </entry>
      <entry>
         <p>Benefit</p>
      </entry>
      <entry>
         <p>Non-Benefit</p>
      </entry>
   </row>

Expected Output Should be:

     <row>
      <entry>Code</entry>
      <entry>
         <p>20000</p>
      </entry>
      <entry>
         <p>30000</p>
      </entry>
      <entry>
         <p>40000</p>
      </entry>
      <entry>
         <p>50000</p>
      </entry>
   </row>
   <row>
      <entry>Level</entry>
      <entry>
         <p>Non-Benefit</p>
      </entry>
      <entry>
         <p>Benefit</p>
      </entry>
      <entry>
         <p>Variable</p>
      </entry>
      <entry>
         <p>Non-Variable</p>
      </entry>
   </row>

As per the Code order match the Description value should pick. I used the variable for Code match. But still it picking the Description value wrongly. So Description should pick as per the Code order.


Solution

  • I am guessing you want to do something like:

    XSLT 2.0

    <xsl:stylesheet version="2.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
    
    <xsl:key name="detail-by-code" match="Detail" use="Code" />
    
    <xsl:template match="/Group">
        <xsl:variable name="headings" select="Maps/Map" />
        <table>
            <!-- header -->
            <row>
                <xsl:for-each select="$headings">
                    <entry>
                        <p>
                            <xsl:value-of select="Code"/>
                        </p>
                    </entry>
                </xsl:for-each>
            </row>
            <!-- data -->
            <xsl:for-each select="Details">
                <xsl:variable name="current-row" select="." />
                <row>
                    <xsl:for-each select="$headings">
                        <entry>
                            <p>
                                <xsl:value-of select="key('detail-by-code', Code, $current-row)/Description"/>
                            </p>
                        </entry>
                    </xsl:for-each>
                </row>
            </xsl:for-each>
        </table>
    </xsl:template>
    
    </xsl:stylesheet>
    

    Using the following test input:

    XML

    <Group>
        <Maps>
            <Map>
                <Code>COLOR</Code>
            </Map>
            <Map>
                <Code>SIZE</Code>
            </Map>
            <Map>
                <Code>SHAPE</Code>
            </Map>
        </Maps>
        <Details>
            <Detail>
                <Code>SIZE</Code>
                <Description>small</Description>
            </Detail>
            <Detail>
                <Code>COLOR</Code>
                <Description>red</Description>
            </Detail>
            <Detail>
                <Code>SHAPE</Code>
                <Description>circle</Description>
            </Detail>
        </Details>
        <Details>
            <Detail>
                <Code>SHAPE</Code>
                <Description>square</Description>
            </Detail>
            <Detail>
                <Code>SIZE</Code>
                <Description>medium</Description>
            </Detail>
            <Detail>
                <Code>COLOR</Code>
                <Description>blue</Description>
            </Detail>
        </Details>
    </Group>
    

    I get:

    Result

    <?xml version="1.0" encoding="UTF-8"?>
    <table>
       <row>
          <entry>
             <p>COLOR</p>
          </entry>
          <entry>
             <p>SIZE</p>
          </entry>
          <entry>
             <p>SHAPE</p>
          </entry>
       </row>
       <row>
          <entry>
             <p>red</p>
          </entry>
          <entry>
             <p>small</p>
          </entry>
          <entry>
             <p>circle</p>
          </entry>
       </row>
       <row>
          <entry>
             <p>blue</p>
          </entry>
          <entry>
             <p>medium</p>
          </entry>
          <entry>
             <p>square</p>
          </entry>
       </row>
    </table>