如何更改根节点的属性值和命名空间URL

时间:2010-12-09 15:15:58

标签: xslt

我想更改xml的命名空间url值。我有一个像以下

的xml
<catalog xmlns="http://someurl"
         xmlns:some="http://someurl2"
         xsi:schemaLocation="http://someurl some.3.0.xsd"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <cd>
        <title>Empire Burlesque</title>
        <artist>Bob Dylan</artist>
        <country>USA</country>
        <company>
            <name>Columbia</name>
        </company>
        <price>10.90</price>
        <year>1985</year>
    </cd>
</catalog>

我正在使用身份转换。有什么办法可以更改名称空间ursl中的文本吗?例如,我想将网址'http:// someurl'更改为'http:// someur2' 和'http:// someurl some.3.0.xsd'到'http:// someurl some.4.0.xsd'

1 个答案:

答案 0 :(得分:10)

这应该这样做:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="1.0"
   xmlns:old="http://someurl" exclude-result-prefixes="old">
   <!-- Identity transform -->
   <xsl:template match="@* | node()">
      <xsl:copy>
         <xsl:apply-templates select="@* | node()"/>
      </xsl:copy>
   </xsl:template>

   <!-- replace namespace of elements in old namespace -->
   <xsl:template match="old:*">
      <xsl:element name="{local-name()}" namespace="http://someurl2">
         <xsl:apply-templates select="@* | node()"/>
      </xsl:element>
   </xsl:template>

   <!-- replace xsi:schemaLocation attribute -->
   <xsl:template match="@xsi:schemaLocation">
      <xsl:attribute name="xsi:schemaLocation">http://someurl some.4.0.xsd</xsl:attribute>
   </xsl:template>
</xsl:stylesheet>

通过样本输入,可以得到:

<?xml version="1.0" encoding="utf-8"?>
<catalog xmlns="http://someurl2"
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xsi:schemaLocation="http://someurl some.4.0.xsd">
   <cd>
      <title>Empire Burlesque</title>
      <artist>Bob Dylan</artist>
      <country>USA</country>
      <company>
         <name>Columbia</name>
      </company>
      <price>10.90</price>
      <year>1985</year>
   </cd>
</catalog>

<强>解释

添加到身份转换的最后两个模板更具体,因此默认优先级高于身份模板。它们分别覆盖“旧”命名空间和xsl:schemaLocation属性中元素的标识模板。

“old:*”的模板输出一个与其替换的元素具有相同本地名称的元素(即没有命名空间的名称),并为其提供新的所需命名空间。

令人高兴的是,XSLT处理器(或者更确切地说,串行器;我使用Saxon 6.5.5进行测试)决定使这个新的命名空间成为默认命名空间,因此它为输出根添加了一个默认的命名空间声明元件。我们没有要求它这样做,理论上这个新命名空间是默认名称还是使用前缀无关紧要。但是你似乎希望它成为默认值,以便很好地解决。