xslt copy-of到结果文档中的不同命名空间

时间:2017-12-18 15:51:23

标签: xslt xslt-2.0

在我的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>

1 个答案:

答案 0 :(得分:1)

您不能使用xsl:copyxsl: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>