更改XSLT中具有未知前缀的名称空间

时间:2019-05-30 19:35:47

标签: xml xslt

我想仅基于namespace-uri使用XSLT更改XML文件中的名称空间,而不知道该名称空间定义了什么前缀。有可能吗?

我得到了一些解决方案,但是当我知道输入内容时,它们仅适用于小文件,并且可以手动设置xsl文件。

我想要实现的目标:

输入XML:

    <?xml version="1.0" encoding="UTF-8"?>
    <re:rootElement xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
xmlns:re="http://something.com/root"
xmlns:ns1="http://something.com/some/schema"
xmlns:cs2="http://something.com/another/schema"
xmlns:ns3="http://something.com/different/schema"
xmlns:xsd="http://www.w3.org/2001/XMLSchema" >
<xsd:import namespace="http://something.com/another/schema" schemaLocation="/schema/location"/>

(下面有多个节点)

带有2个参数的XSLT:

<xsl:param name="old_namespace" select="'http://something.com/another/schema'"/>
<xsl:param name="new_namespace" select="'http://something.com/another/schemaNEW'"/>

并输出为xml:

    <re:rootElement xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
xmlns:re="http://something.com/root"
xmlns:ns1="http://something.com/some/schema"
xmlns:cs2="http://something.com/another/schemaNEW"
xmlns:ns3="http://something.com/different/schema"
xmlns:xsd="http://www.w3.org/2001/XMLSchema" >
 <xsd:import namespace="http://something.com/another/schemaNEW" schemaLocation="/schema/location"/>
(multiple nodes below)

1 个答案:

答案 0 :(得分:1)

更改名称空间节点以及元素和属性名称中使用的名称空间URI并不难。在可识别架构的样式表中,也可以(但可能更难)更改QName类型值中使用的名称空间URI。我怀疑要更改出现的名称空间URI相当困难:

  • 直接在xsi:schemaLocation或xs:import等属性中(除非您枚举此类属性)

  • 以NOTATIONs的名义

  • 的内容带有微语法,例如考虑

<xsl:if test="namespace-uri() = 'http://old-namespace.com/'>

如果只是您要使用的元素和属性中使用的命名空间,则可以使用

<xsl:template match="*[namespace-uri()=$old-namespace]">
  <xsl:element name="{name()}" namespace="{$new-namespace}">
    <xsl:apply-templates select="@*, node()"/>
  </xsl:element>
</xsl:template>

<xsl:template match="@*[namespace-uri()='$old-namespace']">
  <xsl:attribute name="{name()}" namespace="{$new-namespace}" select="."/>
</xsl:template>

以及身份模板(或在3.0中为<xsl:mode on-no-match="shallow-copy"/>),以确保其他元素和属性保持不变。

(这是XSLT 2.0,但很容易用1.0重写)。