2010-08-12 65 views
10

因此,我有一个输入文件在默认名称空间(xmlns="companyURL")中使用我公司的名称空间,但我希望我的输出文件使用默认名称空间(xmlns:cmp="companyURL")以外的其他名称空间。所以我建立基于cmp命名我的文件,但后来我想复制一些内部元素:在XSL翻译中更改XML文件的名称空间

<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。

+0

好问题(+1)。 – 2010-08-12 01:31:14

+0

*“希望我的输出文件使用非默认名称空间”* >>按照您的示例,更改前缀(或从默认值改为前缀)并不意味着改变命名空间。尽管前缀不同,但从XML + NS的角度来看,元素将保持相同(localname +名称空间不变)。 – Abel 2010-08-12 12:11:02

+0

我指的是标签名称前面的可见标识符。 – 2010-08-12 16:28:17

回答

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> 

所提供的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> 
+1

为什么在XSLT中有''? – 2010-08-12 16:26:19

+2

@ adam_0:这将复制元素的所有属性。在你的具体例子中没有属性,但是如果我们想把这个代码作为一般的转换器使用,它必须能够正确地转换所有文档 - 包括其中包含具有属性的元素的文档。 – 2010-08-12 17:42:55

+0

我的XML模式指定不会有属性,所以我猜可以离开这条线很好吗? – 2010-08-12 17:53:35