用XSLT 1更改命名空间(Changing the namespace with xslt 1)

2019-10-17 12:29发布

我有一种比较麻烦的这个比我要和一直没能找到,这似乎是正确的解决方案:

我想简单地更改使用XSLT 1.0 XML文档的命名空间 - withing一个Java应用程序中使用,使用javax.xml.transform中。

这是我的xml文档:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Root xmlns="http://namespace1.org" type="Document" version="V2_2">
    <Content>
        <Text>asdf</Text>
    </Content>
</Root>

这是它应该如何看改造后:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Root xmlns="http://namespace2.org" type="Document" version="V2_2">
    <Content>
        <Text>asdf</Text>
    </Content>
</Root>

这是我的XSLT代码:

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 xmlns="http://namespace2.org">

  <xsl:output omit-xml-declaration="yes" indent="yes"/>
  <xsl:strip-space elements="*"/>

  <xsl:template match="*">
     <xsl:element name="{local-name()}" namespace="http://namespace2.org">
        <xsl:apply-templates select="node()|@*"/>
     </xsl:element>
  </xsl:template>

</xsl:stylesheet>

这是实际输出的改造后,我得到:

<?xml version="1.0" encoding="UTF-8"?>
<ns0:Root xmlns:ns0="http://namespace2.org">2012-11-02T15:39:46.05+01:00DocumentV2_2<ns1:Content xmlns:ns1="http://namespace2.org">
  <ns2:Text xmlns:ns2="http://namespace2.org">asdf</ns2:Text>
 </ns1:Content>
</ns0:Root>

有办法很多前缀补充说,这是我不想要的。

我已经能够通过以下XLST摆脱NS +增量前缀:

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 xmlns="http://namespace2.org"
 xmlns:cmp="http://namespace2.org"
 exclude-result-prefixes="cmp">

  <xsl:output omit-xml-declaration="yes" indent="yes"/>
  <xsl:strip-space elements="*"/>

  <xsl:template match="*">
     <xsl:element name="cmp:{name()}" namespace="http://namespace2.org">
       <xsl:copy-of select="@*"/>
       <xsl:apply-templates/>
     </xsl:element>
 </xsl:template>

</xsl:stylesheet>

这产生以下输出:

<?xml version="1.0" encoding="UTF-8"?>
<cmp:Root xmlns:cmp="http://namespace2.org" type="Document" version="V2_2">
 <cmp:Content>
  <cmp:Text>asdf</cmp:Text>
 </cmp:Content>
</cmp:Root>

但我一直没能摆脱“议定书”的前缀。

任何想法我怎么能达到预期的输出?

Answer 1:

这个通用的转换 (适用于任何XML文档,以及新的命名空间作为全球/外部参数传递):

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>
 <xsl:strip-space elements="*"/>

 <xsl:param name="pNewNS" select="'http://namespace2.org'"/>

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

 <xsl:template match="*">
  <xsl:element name="{name()}" namespace="{$pNewNS}">
   <xsl:copy-of select="namespace::*[not(name() = '')]"/>
   <xsl:apply-templates select="@*|node()"/>
  </xsl:element>
 </xsl:template>

 <xsl:template match="@*">
  <xsl:attribute name="{name()}">
   <xsl:value-of select="."/>
  </xsl:attribute>
 </xsl:template>

 <xsl:template match="@*[namespace-uri()=namespace-uri(/*)]">
  <xsl:attribute name="{name()}" namespace="{$pNewNS}">
   <xsl:value-of select="."/>
  </xsl:attribute>
 </xsl:template>
</xsl:stylesheet>

当施加在提供的XML文档

<Root xmlns="http://namespace1.org" type="Document" version="V2_2">
    <Content>
        <Text>asdf</Text>
    </Content>
</Root>

产生想要的,正确的结果:

<Root xmlns="http://namespace2.org" type="Document" version="V2_2">
   <Content>
      <Text>asdf</Text>
   </Content>
</Root>


文章来源: Changing the namespace with xslt 1