使用xslt更改命名空间1

时间:2012-12-20 14:36:18

标签: java xml xslt xslt-1.0

我遇到的问题比我应该更麻烦,而且找不到合适的解决方案:

我想简单地使用xslt 1.0更改XML文档的命名空间 - 使用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>

但我无法摆脱'cmp'前缀。

任何想法如何实现所需的输出?

1 个答案:

答案 0 :(得分:2)

此通用转换(适用于任何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>