更改元素上的命名空间

时间:2014-03-14 12:00:54

标签: xml xslt namespaces xslt-1.0

我有一个xml文档和一个现有的xslt转换(这两个都是相对较大的预先存在的代码)。

在XML的各个地方,我有像这样声明的可填充字段:

<author i:nil="true" xmlns:i="http://www.w3.org/2001/XMLSchema-instance"/>

但是,我也已经在xml元素中声明了这个名称空间,如下所示:

<message xmlns="http://www.mynamespace.com" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">

我有一个请求,任何nil节点的输出应如下所示:

<author xsi:nil="true" />

即。 i:nil应该变成xsi:nil并且删除在元素上声明的命名空间。

理想情况下,我想修改现有的转换以将其应用于XML中需要这个的任何节点,但是我在编写搜索时遇到一些困难,无法获得有关如何完成此操作的任何结果。如果有人可以提供帮助,那将不胜感激。

(我无法使用任何xslt 2.0聪明,以防万一会影响答案)。

稍微大一点的样本输入:

<message xmlns="http://www.mynamespace.com" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <paper>
    <name>A name</name>
    <author i:nil="true" xmlns:i="http://www.w3.org/2001/XMLSchema-instance" />
  </paper>
  <paper>
    <name>Another name</name>
    <author>
      Peter
    </author>
    <details>
      <publishDate i:nil="true" xmlns:i="http://www.w3.org/2001/XMLSchema-instance" />
      <location>London</location>
    </details>
  </paper>
</message>

期望的输出:

<message xmlns="http://www.mynamespace.com" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <paper>
    <name>A name</name>
    <author xsi:nil="true" />
  </paper>
  <paper>
    <name>Another name</name>
    <author>
      Peter
    </author>
    <details>
      <publishDate xsi:nil="true" />
      <location>London</location>
    </details>
  </paper>
</message>

1 个答案:

答案 0 :(得分:2)

编写一个身份转换和两个单独的模板来处理

  • i
  • 为前缀的属性
  • 具有以i为前缀的属性的元素。

<强>样式表

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:i="http://www.w3.org/2001/XMLSchema-instance">

<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>

<xsl:template match="@*|node()">
    <xsl:copy>
        <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
</xsl:template>

<xsl:template match="attribute::i:*">
    <xsl:attribute name="{concat('xsi:',local-name())}">
        <xsl:value-of select="."/>
    </xsl:attribute>
</xsl:template>

<xsl:template match="*[attribute::i:*]">
    <xsl:element name="{local-name()}" namespace="http://www.mynamespace.com">
        <xsl:apply-templates select="@*|node()"/>
    </xsl:element>
</xsl:template>

</xsl:stylesheet>

<强>输出

Nillability属性现在以xsi:为前缀,而Schema实例名称空间仅在根元素上声明。

<?xml version="1.0" encoding="UTF-8"?>
<message xmlns="http://www.mynamespace.com" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
   <paper>
      <name>A name</name>
      <author xsi:nil="true"/>
   </paper>
   <paper>
      <name>Another name</name>
      <author>
      Peter
    </author>
      <details>
         <publishDate xsi:nil="true"/>
         <location>London</location>
      </details>
   </paper>
</message>