在我的xslt代码中,我可以使用copy-of来复制元素及其后代节点,但问题是生成的模式虽然具有相同的结构但具有不同的命名空间。有什么方法我仍然可以使用副本并完成此操作?我正在使用XSLT 2.0
以下是源和目标XML的示例,可以使用XSL中的copy-of复制cd元素,但它们具有不同的名称空间。
源XML
<catalog xmlns="namespace1">
<cd>
<title>Empire Burlesque</title>
<artist>Bob Dylan</artist>
<country>USA</country>
<company>Columbia</company>
<price>10.90</price>
<year>1985</year>
</cd>
<cd>
<title>Hide your heart</title>
<artist>Bonnie Tyler</artist>
<country>UK</country>
<company>CBS Records</company>
<price>9.90</price>
<year>1988</year>
</cd>
</catalog>
目标XML
<books xmlns="namespace2">
<cd>
<title>Empire Burlesque</title>
<artist>Bob Dylan</artist>
<country>USA</country>
<company>Columbia</company>
<price>10.90</price>
<year>1985</year>
</cd>
<cd>
<title>Hide your heart</title>
<artist>Bonnie Tyler</artist>
<country>UK</country>
<company>CBS Records</company>
<price>9.90</price>
<year>1988</year>
</cd>
</books>
使用Martin Honnen的想法并创建了这个
<xsl:template name="changeNamespace">
<xsl:param name="nodes"/>
<xsl:for-each select="$nodes">
<xsl:choose>
<xsl:when test="count(child::*)>0">
<xsl:element name="newnamespace:{local-name()}">
<xsl:call-template name="changeNamespace">
<xsl:with-param name="nodes" select="./child::*"/>
</xsl:call-template>
</xsl:element>
</xsl:when>
<xsl:otherwise>
<xsl:element name="newnamespace:{local-name()}">
<xsl:value-of select="."/>
</xsl:element>
</xsl:otherwise>
</xsl:choose>
</xsl:for-each>
答案 0 :(得分:1)
您不能使用xsl:copy
或xsl:copy-of
来更改节点的命名空间,您需要使用例如转换节点。
<xsl:template match="ns1:*">
<xsl:element name="ns2:{local-name()}">
<xsl:apply-templates select="@* | node()"/>
</xsl:element>
</xsl:template>
然后假设你有例如范围内为<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:ns1="source-namespace" xmlns:ns2="target-namespace" version="1.0">
,您当然也可以将目标命名空间放入xsl:element
:
<xsl:template match="ns1:*">
<xsl:element name="ns2:{local-name()}" namespace="target-namespace">
<xsl:apply-templates select="@* | node()"/>
</xsl:element>
</xsl:template>
如果您有需要更改命名空间的属性,则需要为属性节点设置类似的模板。
使用XSLT 2.0,您可以简化样式表结构,例如
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xpath-default-namespace="namespace1" xmlns="namespace2" version="2.0">
<xsl:template match="*">
<xsl:element name="{local-name()}">
<xsl:apply-templates select="@* | node()"/>
</xsl:element>
</xsl:template>