我有一些XML声明了一个名称空间,它只用于属性,如:
<?xml version="1.0" encoding="UTF-8"?>
<a xmlns:x="http://tempuri.com">
<b>
<c x:att="true"/>
<d>hello</d>
</b>
</a>
我想使用XSL创建所选节点及其值的副本 - 删除属性。所以我想要的输出是:
<?xml version="1.0" encoding="UTF-8"?>
<b>
<c />
<d>hello</d>
</b>
我有一些XSL几乎可以做到这一点,但我似乎无法阻止它将命名空间声明放在输出的顶级元素中。我的XSL是:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:template match="/">
<xsl:apply-templates select="/a/b"/>
</xsl:template>
<xsl:template match="node()">
<xsl:copy>
<xsl:apply-templates select="node()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
输出的第一个元素是<b xmlns:x="http://tempuri.com">
而不是<b>
。我已经尝试在XSL中声明命名空间并将前缀放在exclude-result-prefixes
列表中,但这似乎没有任何效果。我做错了什么?
更新:我发现通过在XSL中声明命名空间并使用extension-element-prefixes
属性起作用,但这似乎不正确!我想我可以使用它,但我想知道为什么exclude-result-prefixes
不起作用!
更新:实际上,这个extension-element-prefixes
解决方案似乎只适用于XMLSpy的内置XSLT引擎,而不适用于MSXML。
答案 0 :(得分:9)
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"
xmlns:x="http://tempuri.com">
<xsl:template match="/">
<xsl:apply-templates select="/a/b"/>
</xsl:template>
<xsl:template match="*">
<xsl:element name="{local-name(.)}">
<xsl:apply-templates/>
</xsl:element>
</xsl:template>
<xsl:template match="@*">
<xsl:copy/>
</xsl:template>
<!-- This empty template is not needed.
Neither is the xmlns declaration above:
<xsl:template match="@x:*"/> -->
</xsl:stylesheet>
我找到了解释here。
迈克尔凯写道:
exclude-result-prefixes仅影响从中复制的名称空间 样式表由文字结果元素组成,它不影响复制 源文档中的命名空间。
答案 1 :(得分:5)
<xsl:stylesheet
version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:x="http://tempuri.com"
exclude-result-prefixes="x"
>
<!-- the identity template copies everything 1:1 -->
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()" />
</xsl:copy>
</xsl:template>
<!-- this template explicitly cares for namespace'd attributes -->
<xsl:template match="@x:*">
<xsl:attribute name="{local-name()}">
<xsl:value-of select="." />
</xsl:attribute>
</xsl:template>
</xsl:stylesheet>
答案 2 :(得分:4)
试试这个(注意属性copy-namespaces='no'
):
<xsl:template match="node()">
<xsl:copy copy-namespaces="no">
<xsl:apply-templates select="node()"/>
</xsl:copy>
</xsl:template>
答案 3 :(得分:2)
这将从输出中删除x命名空间。
<xsl:namespace-alias result-prefix="#default" stylesheet-prefix="x" />
在处理默认命名空间时,请记住要做两件事。首先将它映射到样式表标记中的某些内容,然后使用名称空间别名将其删除。