xmlxslt

XSLT retrieve value of node named in variable


Still learning XML/XSLT, so apologies if this is simple.

I'm trying to retrieve a specific XML node, whose name is stored in a variable in the XSLT.

i.e. I pass the value "Monat2" in variable monat and it should retrieve the value under the "Monat2" node.

I've tried using <xsl:value-of select="*[local-name()=$monat]"/> to try to refer to the node, but it doesn't seem to work.

Can anyone please advise what I'm doing wrong?

Source XML:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<source>
  <source_records>
    <Klnr>123456</Klnr>
    <Name>BestRun</Name>
    <Pnr>98765 </Pnr>
    <EmpName>Joe Bloggs</EmpName>
    <LA>10 </LA>
    <Lohnart>GEHALT</Lohnart>
    <Monat1>4145.00 </Monat1>
    <Monat2>4513.00 </Monat2>
    <Monat3>4329.00 </Monat3>
    <Monat4>4329.00 </Monat4>
    <Monat5>4329.00 </Monat5>
    <Monat6>0.00 </Monat6>
    <Monat7>0.00 </Monat7>
    <Monat8>0.00 </Monat8>
    <Monat9>0.00 </Monat9>
    <Monat10>0.00 </Monat10>
    <Monat11>0.00 </Monat11>
    <Monat12>0.00 </Monat12>
    <GESAMT>21645.00 </GESAMT>
  </source_records>
  <source_records>
    <Klnr>123456 </Klnr>
    <Name>BestRun</Name>
    <Pnr>98765 </Pnr>
    <EmpName>Joe Bloggs</EmpName>
    <LA>70 </LA>
    <Lohnart>SACHBEZUG PKW</Lohnart>
    <Monat1>510.00 </Monat1>
    <Monat2>510.00 </Monat2>
    <Monat3>510.00 </Monat3>
    <Monat4>510.00 </Monat4>
    <Monat5>510.00 </Monat5>
    <Monat6>0.00 </Monat6>
    <Monat7>0.00 </Monat7>
    <Monat8>0.00 </Monat8>
    <Monat9>0.00 </Monat9>
    <Monat10>0.00 </Monat10>
    <Monat11>0.00 </Monat11>
    <Monat12>0.00 </Monat12>
    <GESAMT>2550.00 </GESAMT>
  </source_records>
</source>

XSLT:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" >
  <!-- <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/> -->
  
  <xsl:template match="/source">
    
    <!-- month to be retrieved -->  
    <xsl:variable name="monat" select="Monat2" />
    
    <!-- cycle through each record -->  
    <xsl:for-each select="source_records">
      
      <!-- rebuild -->            
      <source_records>
        <employeeID>
          <xsl:value-of select="normalize-space(Pnr)" />
        </employeeID>
        <name>
          <xsl:value-of select="EmpName" />
        </name>
        <payCode>
          <xsl:value-of select="normalize-space(LA)" />
        </payCode>                  
        <amount>
          <xsl:value-of select="*[local-name()=$monat]"/>
        </amount>
        
      </source_records>
      
    </xsl:for-each>
  </xsl:template>
</xsl:stylesheet>

Many thanks as always, AJ


Solution

  • Here is an example of using a key:

    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" >
    <xsl:output method="xml"  indent="yes"/>
    
    <xsl:param name="monat"/>
    <xsl:key name="m" match="*" use="substring-after(local-name(), 'Monat')"/>
    
    <xsl:template match="/source">
        <root>
            <xsl:for-each select="key('m', $monat)">
                <xsl:variable name="src" select=".." />
                <source_records>
                    <employeeID>
                        <xsl:value-of select="normalize-space($src/Pnr)" />
                    </employeeID>
                    <name>
                        <xsl:value-of select="$src/EmpName" />
                    </name>
                    <payCode>
                        <xsl:value-of select="normalize-space($src/LA)" />
                    </payCode>
                    <amount>
                        <xsl:value-of select="."/>
                    </amount>
                </source_records>
            </xsl:for-each>
        </root>
    </xsl:template>
    
    </xsl:stylesheet>
    

    When this stylesheet is called with the param monatbeing "2", the result (using your example input) will be:

    <?xml version="1.0"?>
    <root>
      <source_records>
        <employeeID>98765</employeeID>
        <name>Joe Bloggs</name>
        <payCode>10</payCode>
        <amount>4513.00 </amount>
      </source_records>
      <source_records>
        <employeeID>98765</employeeID>
        <name>Joe Bloggs</name>
        <payCode>70</payCode>
        <amount>510.00 </amount>
      </source_records>
    </root>