在 XSL 翻译中更改 XML 文件的命名空间
Posted
技术标签:
【中文标题】在 XSL 翻译中更改 XML 文件的命名空间【英文标题】:Changing namespace for XML file in XSL Translation 【发布时间】:2011-03-28 16:41:57 【问题描述】:所以我有一个输入文件,它在默认命名空间 (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>
不幸的是,这样做是为每个内部元素定义默认命名空间,使文件变得非常冗长和丑陋。简化示例:
来源:
<foo xmlns="companyURL">
<num1>asdf</num1>
<num2>ghjkl</num2>
</foo>
变成:
<cmp:container xmlns:cmp="companyURL">
<num1 xmlns="companyURL">asdf</num1>
<num2 xmlns="companyURL">ghjkl</num2>
</cmp:container>
当然,companyURL
又大又长又丑,而且在两个地方都一样,所以我更希望上面的结果如下:
<cmp:container xmlns:cmp="companyURL">
<cmp:num1>asdf</cmp:num1>
<cmp:num2>ghjkl</cmp:num2>
</cmp:container>
有没有一种简单的方法可以做到这一点,或者我应该将cmp
命名空间下的所有内容都转换为默认命名空间?如果可能,我更愿意使用显式命名空间命名,这有助于根据我的经验理解 XSLT。
【问题讨论】:
好问题 (+1)。请参阅我的答案以获得简短的解决方案,:) "希望我的输出文件使用默认命名空间以外的其他内容" >> 按照您的示例,更改前缀(或从默认到前缀)并不意味着更改命名空间。从 XML+NS 的角度来看,元素将保持相等(本地名称 + 命名空间不变),即使前缀不同。 我指的是标签名称前面的可见标识符。 【参考方案1】:这种转变:
<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>
在提供的 XML 文档上执行时:
<foo xmlns="companyURL">
<num1>asdf</num1>
<num2>ghjkl</num2>
</foo>
产生想要的正确结果:
<cmp:container xmlns:cmp="CompanyURL">
<cmp:num1>asdf</cmp:num1>
<cmp:num2>ghjkl</cmp:num2>
</cmp:container>
【讨论】:
为什么你的 XSLT 中有<xsl:copy-of select="@*"/>
?
@adam_0:这会复制元素的所有属性。在您的具体示例中没有属性,但如果我们想将此代码用作通用转换器,它必须能够正确转换所有文档 - 包括其中包含具有属性的元素的文档。
如果你 100% 确定你可以删除它,但离开它不会有任何伤害——根本不会复制任何属性。拥有更多通用代码总是更好。想象一下,明天模式会发生变化,并且会有属性。然后你需要添加属性的复制。如果您从一开始就使用更通用的代码,那么架构中的这种更改根本不会影响您。
我刚刚想到的后续行动:我可以通过将 <xsl:element name="cmp:name()" namespace="CompanyURL">
的顶部模板行更改为 <xsl:element name="cmp:local-name()" namespace="CompanyURL">
来使任何命名空间前缀都可以使用(有效地修剪掉任何命名空间前缀并添加我自己的)?
@adam_0:是的,这是进行前缀重命名的方法。以上是关于在 XSL 翻译中更改 XML 文件的命名空间的主要内容,如果未能解决你的问题,请参考以下文章