覆盖xmlns会破坏xslt结果

时间:2016-07-01 08:51:38

标签: xml xslt notepad++ xslt-1.0

问题如下,我有一个简单的XML文件:

<table xmlns="http://www.w3.org/TR/html4/">
    <tr>
        <td>
            Does not work
        </td>
    </tr>
</table>

和XSL转换文件

<xsl:transform version="1.0" xmlns="http://www.w3.org/TR/html4/" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:template match="td">
        It works
    </xsl:template>
</xsl:transform>

如果&#34; td&#34;匹配我希望看到&#34;它有效&#34;作为模板定义的输出。 如果&#34; td&#34;是不匹配的,那么我希望看到&#34;不起作用&#34;因为默认模板将输出未由自定义模板处理的所有节点值。 结果:

<?xml version="1.0"?>


        Does not work

但是,如果我将名称空间声明更改为xmlns:html =&#34; ...&#34;那么结果就会改变。

的xml:

<html:table xmlns:html="http://www.w3.org/TR/html4/">
    <html:tr>
        <html:td>
            Does not work
        </html:td>
     </html:tr>
</html:table>

XSLT:

<xsl:transform version="1.0" xmlns:html="http://www.w3.org/TR/html4/"  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:template match="html:td">
        It works
    </xsl:template>
</xsl:transform>

结果:

<?xml version="1.0"?>


    It works

这是一个简单的例子来隔离问题,真正应用程序的xml是由第三方软件提供的,将xmlns声明覆盖到xmlns:不是一个选项。我的问题是,如何让这个工作,结果:&#34;它工作&#34;,而不更改xmlns。

对于转换,我使用带有XML工具插件的notepad ++,其中有一个XSL转换选项。

提前谢谢

2 个答案:

答案 0 :(得分:3)

转换第一个文档(具有默认命名空间的文档):

<table xmlns="http://www.w3.org/TR/html4/">
    <tr>
        <td>
            Does not work
        </td>
    </tr>
</table>

使用第二个XSLT样式表:

<xsl:transform version="1.0" xmlns:html="http://www.w3.org/TR/html4/"  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:template match="html:td">
        It works
    </xsl:template>
</xsl:transform>

你会对结果感到惊讶:

<?xml version="1.0" encoding="UTF-8"?>


    It works

使用前缀声明命名空间:

xmlns:html="http://www.w3.org/TR/html4/"

是处理具有默认命名空间的XML输入文档的常用方法。如果样式表中有这样的声明,html:td将与输入文档中具有默认命名空间的td元素完全相同。

这是因为前缀实际上是不相关的。像html:这样的前缀没有任何意义,它是有意义的命名空间URI。前缀只是一种简写,可以避免为每个元素键入(或读取)命名空间URI。你应该想到像

这样的元素
<table xmlns="http://www.w3.org/TR/html4/">

作为

<{http://www.w3.org/TR/html4/}table>

,并且,类似地,想到

<html:table xmlns:html="http://www.w3.org/TR/html4/">

同样:

<{http://www.w3.org/TR/html4/}table>

另外,简要评论:

<xsl:transform version="1.0" xmlns="http://www.w3.org/TR/html4/">

请记住,XSLT样式表只是一个常规XML文件,所有XML规则都适用于它。在XSLT样式表中声明默认命名空间的唯一效果是:所有没有前缀的元素(即不在其他命名空间中)都将与此命名空间相关联。

但是,由于XSLT样式表中的所有元素都有前缀xsl:,因此默认命名空间不会执行任何操作。在样式表中:

<?xml version="1.0" encoding="UTF-8" ?>
<xsl:transform version="1.0" xmlns="http://www.w3.org/TR/html4/"  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:template match="/">
        <result>it works</result>
    </xsl:template>
</xsl:transform>

您实际上可以看到默认命名空间的作用,因为结果将是:

<?xml version="1.0" encoding="UTF-8"?>
<result xmlns="http://www.w3.org/TR/html4/">it works</result>

答案 1 :(得分:1)

  

我的问题是,如何让这个工作,结果:&#34;它工作&#34;,没有   改变xmlns。

<xsl:transform version="1.0" 
xmlns:ns="http://www.w3.org/TR/html4/" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 

<xsl:template match="ns:td">
        It works
</xsl:template>

</xsl:transform>