ramanareddy438
ramanareddy438

Reputation: 145

Getting the value of prefixed XML tag in XSLT

I am trying to get the value of prefixed XML tag data in XSLT.

Sample XML:

    <?xml version="1.0" encoding="utf-8"?>
<emp xmlns="http://www.w3.org/2005/Atom" xmlns:m="http://www.w3.org/1999/XSL/dataservices/metadata" xmlns:d="http://www.w3.org/1999/XSL/dataservices">
    <record>
        <info type="application/xml">
            <m:employee>
                <d:name>11278</d:name>
            </m:employee>
        </info>
    </record>
</emp>

I want to get the data of the name elements using XSLT. I tried different options.

    <?xml version="1.0" encoding="ISO-8859-1"?>
    <xsl:stylesheet version="1.1" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
        xmlns:m="http://www.w3.org/1999/XSL/dataservices/metadata" 
        xmlns:d="http://www.w3.org/1999/XSL/dataservices">
    <xsl:output method='html' version='1.0' encoding='UTF-8' indent='yes'/>
    <xsl:template match="/">
      <html>
          <body>
            <h2><i>Emp Compensastion Data</i></h2>
            <div class="content-holder">
                <div>Name of the employee: <xsl:value-of select="emp/record/info/m:employee/d:name"/></div>
                <div>Name of the Employee: <xsl:value-of select="//*[local-name()='m:employee']/*[local-name()='d:name']"/></div>
                <div>Name of the Employee: <xsl:value-of select="//*[name()='m:employee']/*[name()='d:name']"/></div>
            </div>
          </body>
      </html>
    </xsl:template>
    </xsl:stylesheet>

I am a newbie in XSL transformations. Please help.

Note: I was trying to create HTML using XSL transformations.

Upvotes: 2

Views: 642

Answers (2)

Iurii  Kvashuk
Iurii Kvashuk

Reputation: 409

If I understand right, you are trying three different xpaths to get values and nothing works. Is that so?

        <div class="content-holder">
            <div>Name of the employee: <xsl:value-of select="emp/record/info/m:employee/d:name"/></div>
            <div>Name of the Employee: <xsl:value-of select="//*[local-name()='m:employee']/*[local-name()='d:name']"/></div>
            <div>Name of the Employee: <xsl:value-of select="//*[name()='m:employee']/*[name()='d:name']"/></div>
        </div>

However, I've tried the transform and got the following result:

<?xml version = '1.0' encoding = 'UTF-8'?>
<html xmlns:d="http://www.w3.org/1999/XSL/dataservices" xmlns:m="http://www.w3.org/1999/XSL/dataservices/metadata" xmlns:ns0="http://www.w3.org/2005/Atom">
   <body>
      <h2><i>Emp Compensastion Data</i>
      </h2>
      <div class="content-holder">
         <div>Name of the employee:</div>
         <div>Name of the Employee:</div>
         <div>Name of the Employee:11278</div>
      </div>
   </body>
</html>

So, I can assert that the third xpath is working.

The first xpath does not work because there is also another problem: the emp element is in the namespace defined by xmlns="http://www.w3.org/2005/Atom" and this needs to be considered, for example, I've added xmlns:ns0="http://www.w3.org/2005/Atom" into my stylesheet attributes:

<xsl:stylesheet version="1.1" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:ns0="http://www.w3.org/2005/Atom"
                xmlns:m="http://www.w3.org/1999/XSL/dataservices/metadata" xmlns:d="http://www.w3.org/1999/XSL/dataservices">

And now I got the following first xpath. It also works:

<div>Name of the employee:<xsl:value-of select="ns0:emp/ns0:record/ns0:info/m:employee/d:name"/></div>

Upvotes: 2

michael.hor257k
michael.hor257k

Reputation: 116957

<xsl:value-of select="emp/record/info/m:employee/d:name"/>

This is your best attempt. The reason why it doesn't work is that your XML defines a default namespace xmlns="http://www.w3.org/2005/Atom" and all the unprefixed elements - such as emp, record and info - are in this namespace.

You must declare this namespace in your stylesheet, assign it a prefix, and use that prefix when addressing the unprefixed elements in the source XML:

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:a="http://www.w3.org/2005/Atom"
xmlns:m="http://www.w3.org/1999/XSL/dataservices/metadata" 
xmlns:d="http://www.w3.org/1999/XSL/dataservices"
exclude-result-prefixes="a m d">
<xsl:output method='html' encoding='UTF-8'/>

<xsl:template match="/">
    <html>
        <body>
            <h2><i>Emp Compensastion Data</i></h2>
            <div class="content-holder">
                <div>Name of the employee: <xsl:value-of select="/a:emp/a:record/a:info/m:employee/d:name"/></div>
            </div>
        </body>
    </html>
</xsl:template>

</xsl:stylesheet>

Note:
You should never have to use a hack like *[local-name()='m:employee']. But you should also know that the local name of an element excludes the prefix - therefore the predicate will never be true.

Upvotes: 2

Related Questions