Mae*_*o13 3 xslt xpath namespaces
当根元素具有默认的命名空间属性而不是它时,我在xslt行为中遇到了一个特殊的区别.
我想知道为什么会出现这种差异.
XML输入是
<root>
<content>xxx</content>
</root>
Run Code Online (Sandbox Code Playgroud)
应用以下转换时
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="/">
<root>
<xsl:apply-templates/>
</root>
</xsl:template>
<xsl:template match="content">
<w>x</w>
</xsl:template>
</xsl:stylesheet>
Run Code Online (Sandbox Code Playgroud)
结果是预期的
<?xml version="1.0" encoding="UTF-8"?>
<root>
<w>x</w>
</root>
Run Code Online (Sandbox Code Playgroud)
但是当应用相同的转换时
<root xmlns="http://test.com">
<content>xxx</content>
</root>
Run Code Online (Sandbox Code Playgroud)
结果是不同的,并且基于默认模板的应用(有效输出文本节点值'xxx'):
<?xml version="1.0" encoding="UTF-8"?>
<root>xxx</root>
Run Code Online (Sandbox Code Playgroud)
加成
如果这是这种情况下的预期行为,那么content
在第二种情况下需要匹配元素的匹配属性值是什么?
这是XPath/XSLT中最常见的FAQ.
XPath将未加前缀的元素名称视为属于"无名称空间".
在W3C XPath规范说:
如果QName没有前缀,则名称空间URI为null.
因此,在具有默认命名空间的文档中,引用具有无前缀名称的元素(例如"someName")不会选择任何内容,因为XML文档中的"无命名空间"中没有任何元素,但someName
意味着名称为" someName",属于"无命名空间".
解决方案:
如果我们想要按名称选择元素,我们必须在该名称前加上前缀,并且前缀必须与默认名称空间相关联.
这种转变:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:x="http://test.com" exclude-result-prefixes="x">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="/">
<root>
<xsl:apply-templates/>
</root>
</xsl:template>
<xsl:template match="x:content">
<w>x</w>
</xsl:template>
</xsl:stylesheet>
Run Code Online (Sandbox Code Playgroud)
当应用于提供的具有默认命名空间的XML文档时:
<root xmlns="http://test.com">
<content>xxx</content>
</root>
Run Code Online (Sandbox Code Playgroud)
产生想要的,正确的结果:
<root>
<w>x</w>
</root>
Run Code Online (Sandbox Code Playgroud)