我遇到了一个xsl模板的问题,该模板输出的节点属于空的xmlns属性。
模板是:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0"/>
<xsl:template match="/">
<X xmlns="a_ns">
<Y>
<xsl:value-of select="a/b/b2"/>
</Y>
<Z>
<xsl:copy-of select="a/d/d1/d11"/>
</Z>
</X>
</xsl:template>
输入是:
<a>
<b>
<b1>b1_text</b1>
<b2>b2_text</b2>
</b>
<c>
<c1>c1_text</c1>
<c2>c2_text</c2>
</c>
<d>
<d1>
<d11>
<d111 ls="op">d111_text</d111>
<d112>d112_text</d112>
</d11>
<d12>d12_text</d12>
</d1>
<d2>d2_text</d2>
<d3>d3_text</d3>
</d>
输出:
<?xml version="1.0" encoding="utf-8"?>
<X xmlns="a_ns">
<Y>b2_text</Y>
<Z>
<d11 xmlns="">
<d111 ls="op">d111_text</d111>
<d112>d112_text</d112>
</d11>
</Z>
</X>
如何修改模板以便xmlns =“”不再出现?
谢谢!
答案 0 :(得分:3)
此转化:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="/">
<X xmlns="a_ns">
<Y>
<xsl:value-of select="a/b/b2"/>
</Y>
<Z>
<xsl:apply-templates select="a/d/d1/d11"/>
</Z>
</X>
</xsl:template>
<xsl:template match="*[ancestor-or-self::d11]">
<xsl:element name="{name()}" namespace="a_ns">
<xsl:copy-of select="@*"/>
<xsl:apply-templates/>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
应用于提供的XML文档:
<a>
<b>
<b1>b1_text</b1>
<b2>b2_text</b2>
</b>
<c>
<c1>c1_text</c1>
<c2>c2_text</c2>
</c>
<d>
<d1>
<d11>
<d111 ls="op">d111_text</d111>
<d112>d112_text</d112>
</d11>
<d12>d12_text</d12>
</d1>
<d2>d2_text</d2>
<d3>d3_text</d3>
</d>
</a>
生成想要的正确结果:
<X xmlns="a_ns">
<Y>b2_text</Y>
<Z>
<d11>
<d111 ls="op">d111_text</d111>
<d112>d112_text</d112>
</d11>
</Z>
</X>
<强>解释强>:
xsl:copy-of
生成由其select
属性中指定的表达式选择的每个节点的精确副本。因此,它不能用于更改任何复制元素的(默认)命名空间。
在这种情况下复制的元素属于“无命名空间”。复制的元素仍然属于“无命名空间”这一事实由xmlns=""
表示 - 正确的应该是 - 由XSLT处理器。
答案 1 :(得分:0)
要注意的关键是要更改d11等元素的名称。在输入中,名称为{} d11 - 即无名称空间中的d11,而在输出中,您希望将其命名为{a_ns} d11 - 即命名空间a_ns中的d11。 xsl:copy-of指令完全复制节点,因此它保留名称{} d11,并且序列化程序必须添加xmlns =“”声明以确保它保留此名称。要更改名称(特别是名称的名称空间部分),您需要使用Dimitre提供的过程转换节点而不是复制它们。