在XSL Translation中更改XML文件的命名空间

ada*_*m_0 10 xml xslt namespaces transform

所以我有一个输入文件,在默认的命名空间(xmlns="companyURL")中使用我公司的命名空间,但我希望我的输出文件使用默认命名空间(xmlns:cmp="companyURL")之外的其他东西.所以我使用cmp命名空间构造我的文件,但后来我想复制一些内部元素:

<xsl:element name="cmp:container">
  <xsl:for-each select="foo">
    <xsl:copy-of select="." />
  </xsl:for-each>
</xsl:element>
Run Code Online (Sandbox Code Playgroud)

不幸的是,这样做是为每个内部元素定义默认命名空间,使文件非常冗长和丑陋.简化示例:

来源:

<foo xmlns="companyURL">
  <num1>asdf</num1>
  <num2>ghjkl</num2>
</foo>
Run Code Online (Sandbox Code Playgroud)

变成:

<cmp:container xmlns:cmp="companyURL">
  <num1 xmlns="companyURL">asdf</num1>
  <num2 xmlns="companyURL">ghjkl</num2>
</cmp:container>
Run Code Online (Sandbox Code Playgroud)

当然,companyURL它既大又长又丑,而且在两个地方都是一样的,所以我希望上面的结果只是如下:

<cmp:container xmlns:cmp="companyURL">
  <cmp:num1>asdf</cmp:num1>
  <cmp:num2>ghjkl</cmp:num2>
</cmp:container>
Run Code Online (Sandbox Code Playgroud)

有没有一种简单的方法可以做到这一点,还是应该将cmp命名空间下的所有内容转换为默认命名空间?我希望尽可能使用显式命名空间命名,它有助于理解我的经验中的XSLT.

Dim*_*hev 10

这种转变:

 <xsl:template match="*">
     <xsl:element name="cmp:{name()}" namespace="CompanyURL">
       <xsl:copy-of select="@*"/>
       <xsl:apply-templates/>
     </xsl:element>
 </xsl:template>
 <xsl:template match="/*">
     <cmp:container xmlns:cmp="CompanyURL">
       <xsl:copy-of select="@*"/>
       <xsl:apply-templates/>
     </cmp:container>
 </xsl:template>
</xsl:stylesheet>
Run Code Online (Sandbox Code Playgroud)

在提供的XML文档上执行时:

<foo xmlns="companyURL">
  <num1>asdf</num1>
  <num2>ghjkl</num2>
</foo>
Run Code Online (Sandbox Code Playgroud)

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

<cmp:container xmlns:cmp="CompanyURL">
   <cmp:num1>asdf</cmp:num1>
   <cmp:num2>ghjkl</cmp:num2>
</cmp:container>
Run Code Online (Sandbox Code Playgroud)

  • @ adam_0:复制元素的所有属性.在您的具体示例中,没有属性,但是如果我们想要将此代码用作一般转换器,则它必须能够正确转换所有文档 - 包括具有属性的元素. (2认同)
  • 如果您100%确定可以删除它,但保留它不会伤害任何东西 - 根本不会复制任何属性.拥有更多通用代码总是更好.想象一下,明天架构会发生变化,并且会有属性.然后,您需要添加属性的复制.如果您从一开始就使用了更通用的代码,那么架构中的这种更改根本不会影响您. (2认同)
  • @ adam_0:是的,这是进行前缀重命名的方法. (2认同)