user3091422
user3091422

Reputation: 13

XSLT 1.0 Mapping checking the current node

I am beginning with XSLT and am trying to solve the following problem:

This is my XML code:

<?xml version="1.0" encoding="UTF-8"?>
<ns0:MT_SOURCE xmlns:ns0="urn:test:xslt:chris">
   <FirstName>Chris</FirstName>
   <LastName>Rock</LastName>
   <Address>
      <Street>Musterstr.</Street>
      <StreetNumber>2</StreetNumber>
      <PostalCode>12345</PostalCode>
      <City>Stadt</City>
      <Country>Deutschland</Country>
   </Address>
</ns0:MT_SOURCE>

Now I want to transform this to another structure where I map the country value to a code. Statically I got it working the following way:

<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:a="urn:test:xslt:chris">

        <xsl:variable name="map">
            <map>
        <entry from="Deutschland">DE</entry>
        <entry from="England">EN</entry>
        <entry from="USA">US</entry>
            </map>
        </xsl:variable>

    <xsl:template match="/">
        <a:MT_TARGET>
            <NAME>
                <xsl:value-of select="concat(concat(a:MT_SOURCE/FirstName,' '),a:MT_SOURCE/LastName)"/>
            </NAME>
            <COUNTRYCODE>
                <xsl:value-of select="document('')//xsl:variable[@name='map']/map/entry[@from='England']"/>
            </COUNTRYCODE>
            <CITY>
                <xsl:value-of select="a:MT_SOURCE/Address/City"/>
            </CITY>
            <POSTALCODE>
                <xsl:value-of select="a:MT_SOURCE/Address/PostalCode"/>
            </POSTALCODE>
            <STREET>
                <xsl:value-of select="concat(a:MT_SOURCE/Address/Street,a:MT_SOURCE/Address/StreetNumber)"/>
            </STREET>
        </a:MT_TARGET>
    </xsl:template>
</xsl:stylesheet>

The important part now is the following line:

<COUNTRYCODE> 
<xsl:value-of select="document('')//xsl:variable[@name='map']/map/entry[@from='England']"/>
</COUNTRYCODE>

Statically this is working, so I am getting EN instead of England in the countrycode output. But what I would rather need is that the Country field is evaluated and that from the mapping table the correct value is taking which belongs to it.

Could you please give me how to modify my code in order to get this to work? I tried using current() but it does not seem to do anything.

Upvotes: 1

Views: 350

Answers (2)

Mathias M&#252;ller
Mathias M&#252;ller

Reputation: 22617

This is a way to do it. Make sure you use current() correctly.

Also, I simplified your stylesheet:

  • Removed a redundant nesting map element in the variable you create.
  • Let the template match "/a:MT_SOURCE" simplifies the XSLT code greatly as you can see
  • If you set the output method to XML and indent it, this improves the readability of output, since you are outputting XML elements anyway

Also note that it is confusing to have the same namespaces with different prefixes in the XML input and XSLT stylesheet. Always use the same prefix to denote the same namespace.

The entire stylesheet:

<?xml version="1.0"?>

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
xmlns:a="urn:test:xslt:chris">

 <xsl:output method="xml" indent="yes"/>  

 <xsl:variable name="map">
    <entry from="Deutschland">DE</entry>
    <entry from="England">EN</entry>
    <entry from="USA">US</entry>
 </xsl:variable>

 <xsl:template match="/a:MT_SOURCE">
    <a:MT_TARGET>
        <NAME>
            <xsl:value-of select="concat(concat(FirstName,' '),LastName)"/>
        </NAME>
        <COUNTRYCODE>
            <xsl:value-of select="document('')//xsl:variable[@name='map']/entry[@from=current()/Address/Country]"/>
        </COUNTRYCODE>
        <CITY>
            <xsl:value-of select="Address/City"/>
        </CITY>
        <POSTALCODE>
            <xsl:value-of select="Address/PostalCode"/>
        </POSTALCODE>
        <STREET>
            <xsl:value-of select="concat(Address/Street,Address/StreetNumber)"/>
        </STREET>
    </a:MT_TARGET>
 </xsl:template>

</xsl:stylesheet>

Upvotes: 0

Andreas
Andreas

Reputation: 1250

Just change the important part into

<COUNTRYCODE>
  <xsl:value-of select="document('')//xsl:variable[@name='map']/map/entry[@from=current()/a:MT_SOURCE/Address/Country]"/>
</COUNTRYCODE>

This way current() is working.

Upvotes: 1

Related Questions