如何使用命名空间进行XML的XSL转换?

时间:2015-08-18 05:18:57

标签: xml xslt namespaces

我有一个带命名空间的XML,我需要对其进行转换。 这是我的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>

这是我的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>

当我的XML没有任何命名空间时,此XSLT正常工作。但是,当我添加命名空间时,它无法正常工作 - 不显示我需要的数据。

为了让它正常工作,我该怎么做?我应该在XSLT中添加命名空间吗?如果是,那怎么样?使用这样的前缀:

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

或没有这样的

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

如果我添加带前缀的命名空间,我应该在XSLT中为所有元素添加前缀吗? 我试图通过添加命名空间来解决我的问题,但无法使其正常工作。

也许有人会帮我这个? 非常感谢你提前!

2 个答案:

答案 0 :(得分:2)

我能看到你唯一一个按名称引用元素的地方就在这里(确切地说是title元素):

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

在您发布的XML输入中具有默认命名空间,title元素继承该命名空间。要匹配命名空间中的元素,您需要声明一个指向命名空间uri的前缀,例如:

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

然后像这样使用该前缀:

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

<强> Xsltransform Demo

答案 1 :(得分:1)

在xslt中添加命名空间,如下所示。 相应地更改模板和for-each。

<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">