Ms.Smith
Ms.Smith

Reputation: 483

How to make XSL transformation of XML with a namespace?

I have XML with a namespace and I need to transform it. Here is my XML:

<HouseOfWindsorFamily
    xmlns="http://www.myexample.com">

    <person id="1.1">
        <title>Queen Elizabeth II</title>
        <familyName>Windsor</familyName>
        <name>Elizabeth Alexandra Mary</name>
        <dob>1926-04-21</dob>
        <parents>
           <father>King George IV</father>
           <mother>Elizabeth Bowes-Lyon</mother>
        </parents>
        <siblings>
            <sibling>1.3</sibling>
        </siblings>
        <spouse>
            <current>1.2</current>
        </spouse>
        <children>
            <child number="01">2.1</child>
            <child number="02">2.2</child>
            <child number="03">2.3</child>
            <child number="04">2.4</child>
        </children>
    </person>
    <person id="1.2">
        <title>Prince Philip, Duke of Edinburgh</title>
        <familyName>Mountbatten</familyName>
        <name>Philip</name>
        <dob>1921-06-10</dob>
        <parents>
            <father>Prince Andrew of Greece and Denmark</father>
            <mother>Princess Alice of Battenberg</mother>
        </parents>
        <spouse>
            <current>1.1</current>
        </spouse>
     </person>
    <person id="1.3">
        <title>Princess Margaret, Countess of Snowdon</title>
        <familyName>Windsor</familyName>
        <name>Margaret Rose</name>
        <dob>1930-08-21</dob>
        <parents>
            <father>King George IV</father>
            <mother>Elizabeth Bowes-Lyon</mother>
        </parents>
        <siblings>
            <sibling>1.1</sibling>
        </siblings>
    </person>
    <person id="2.1">
        <title>Prince Charles, Prince of Wales</title>
        <familyName>Mountbatten-Windsor</familyName>
        <name>Charles Philip Arthur George</name>
        <dob>1948-11-14</dob>
        <parents>
            <father>1.2</father>
            <mother>1.1</mother>
        </parents>
    </person>
    <person id="2.2">
        <title>Princess Anne, Princess Royal</title>
        <familyName>Mountbatten-Windsor</familyName>
        <name>Anne Elizabeth Alice Louise</name>
        <dob>1950-08-15</dob>
        <parents>
            <father>1.2</father>
            <mother>1.1</mother>
        </parents>
    </person>
    <person id="2.3">
        <title>Prince Andrew, Duke of York</title>
        <familyName>Mountbatten-Windsor</familyName>
        <name>Andrew Albert Christian Edward</name>
        <dob>1960-02-19</dob>
        <parents>
            <father>1.2</father>
            <mother>1.1</mother>
        </parents>
     </person>
    <person id="2.4">
        <title>Prince Edward, Earl of Wessex</title>
        <familyName>Mountbatten-Windsor</familyName>
        <name>Edward Antony Richard Louis</name>
        <dob>1964-03-10</dob>
        <parents>
            <father>1.2</father>
            <mother>1.1</mother>
        </parents>
    </person>
</HouseOfWindsorFamily>

Here is my XSLT:

 <?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
            xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

    <xsl:template match="/*">
        <xsl:for-each select="/*/*">
            <xsl:if test="@id = '1.1'">
                <xsl:copy>
                    <xsl:apply-templates select="* | @*"/>
                </xsl:copy>
            </xsl:if>
        </xsl:for-each>
    </xsl:template>

    <xsl:template match="* | @*">
        <xsl:copy>
           <xsl:choose>
               <xsl:when test="string-length(.) &lt; 5 and contains(text(), '.')">
                   <xsl:variable name="newid" select="text()"/>
                   <xsl:value-of select="../../../*[@id = $newid]/title"/>
               </xsl:when>
               <xsl:otherwise>
                   <xsl:apply-templates/>
               </xsl:otherwise>
           </xsl:choose>
        </xsl:copy>
    </xsl:template>

</xsl:stylesheet>

This XSLT works OK when my XML doesn't have any namespace. But when I add the namespace it doesn't work correctly - doesn't show the data I need.

What should I do in order to get it working? Should I add a namespace to my XSLT? And if yes then how? With a prefix like this:

<xmlns:ns1="http://www.myexample.com"> 

or without it like this

<xmlns="http://www.myexample.com">

If I add a namespace with prefix should I add prefix to all elements in XSLT? I've tried to fix my problem with adding a namespace but can't make it to work correctly.

Maybe someone would help me with this? Thank you very much in advance!

Upvotes: 0

Views: 84

Answers (2)

Sorter
Sorter

Reputation: 10210

Add the namespace in your xslt as follows. Change the template and for-each accordingly.

<xsl:stylesheet version="1.0"
         t:xmlns="http://www.myexample.com"   xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:template match="/t:HouseOfWindsorFamily">
    <xsl:for-each select="t:person">

Upvotes: 1

har07
har07

Reputation: 89285

The only place I can see you reference element by name is here (the title element to be precise) :

<xsl:value-of select="../../../*[@id = $newid]/title"/>

Having default namespace as in the XML input you posted, title elements inherit that namespace. To match element in namespace, you need to declare a prefix that point to the namespace uri, for example :

<xsl:stylesheet version="1.0"
            xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
            xmlns:ns1="http://www.myexample.com"> 

and then use that prefix like so :

<xsl:value-of select="../../../*[@id = $newid]/ns1:title"/>

Xsltransform Demo

Upvotes: 2

Related Questions