2010-11-05 54 views
5

元素的命名空间,我想使这个更改使用XSLT

<hello> 
    <one> 
    <paragraph>p1</paragraph> 
    </one> 
</hello> 

这个

<x:hello y:an_attribute="a value for an_attribute" xmlns:x="some_new_namespace" xmlns:y="other_ns"> 
    <one> 
    <paragraph>p1</paragraph> 
    </one> 
</x:hello> 

这是我想出了样式表:

<xsl:stylesheet version="1.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:output method="xml" indent="yes"/> 

    <xsl:param name="element_localname" select="'hello'"/> 


    <xsl:template match="node()"> 
     <xsl:choose> 
      <xsl:when test="local-name() = $element_localname"> 
       <xsl:element name="{$element_localname}" namespace="some_new_namespace"> 
        <xsl:attribute name="an_attribute" namespace="other_ns">a value for an_attribute</xsl:attribute> 
        <xsl:apply-templates select="node()"/> 
       </xsl:element> 
      </xsl:when> 

      <!-- copy the rest as is --> 
      <xsl:otherwise> 
       <xsl:copy> 
        <xsl:apply-templates select="node()" /> 
       </xsl:copy> 
      </xsl:otherwise> 

     </xsl:choose> 
    </xsl:template> 

</xsl:stylesheet> 

但出于一些奇怪的原因,我添加到元素的属性与根元素本身具有相同的名称空间?为什么?

<ns0:hello xmlns:ns0="other_ns" ns0:an_attribute="a value for an_attribute"> 
    <one> 
    <paragraph>p1</paragraph> 
    </one> 
</ns0:hello> 

谢谢您的阅读。

+0

通过在xsltproc你的转换运行源给我'<你好的xmlns = “some_new_namespace” 的xmlns:ns_1 = “other_ns” ns_1:an_attribute =“an_attribute的值”>''hello'元素,这似乎是你想要的。不知道这是XSL 1.0还是XSL 2.0? – 2010-11-05 14:06:16

+0

谢谢你的尝试。我正在使用xslt处理器中的eclipse wtp版本。我不知道使用什么实现。 – Luca 2010-11-05 15:02:08

+0

好问题,+1。看到我的答案比现在接受的更简单和更短的解决方案。 :) – 2010-11-05 16:02:04

回答

0

这个样式表:

<xsl:stylesheet version="1.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:x="some_new_namespace" 
    xmlns:y="other_ns"> 
    <xsl:output method="xml" indent="yes"/> 
    <xsl:param name="element_localname" select="'hello'"/> 
    <xsl:template match="node()|@*" name="identity"> 
     <xsl:copy> 
      <xsl:apply-templates select="node()|@*"/> 
     </xsl:copy> 
    </xsl:template> 
    <xsl:template match="*"> 
     <xsl:choose> 
      <xsl:when test="local-name() = $element_localname"> 
       <xsl:element name="x:{$element_localname}"> 
        <xsl:attribute name="y:an_attribute"> 
         <xsl:text>a value for an_attribute</xsl:text> 
        </xsl:attribute> 
        <xsl:apply-templates select="node()|@*"/> 
       </xsl:element> 
      </xsl:when> 
      <xsl:otherwise> 
       <xsl:call-template name="identity" /> 
      </xsl:otherwise> 
     </xsl:choose> 
    </xsl:template> 
</xsl:stylesheet> 

输出:

<x:hello y:an_attribute="a value for an_attribute" 
     xmlns:y="other_ns" xmlns:x="some_new_namespace"> 
    <one> 
     <paragraph>p1</paragraph> 
    </one> 
</x:hello> 
+0

谢谢,这个作品。你解决了我的问题:)你有一个想法,为什么我的例子不? – Luca 2010-11-05 15:04:56

+0

@Luca:你很好。这是您的代码输出:' p1'So ,你有一个defalut命名空间根元素,它的属性在一个not null命名空间下(前缀是由namespaces fixup自动添加的)和一个重置默认命名空间声明'xmlns =“”'(在XML 1.1中也可以重新设置前缀名称空间声明。) 。底线:如果你想要一个特定的前缀名称空间URI绑定,将其声明到样式表中。 – 2010-11-05 15:26:08

4

这比它似乎简单得多:

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

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

<xsl:template match="/*"> 
    <x:hello y:an_attribute="a value for an_attribute"> 
    <xsl:apply-templates/> 
    </x:hello> 
</xsl:template> 
</xsl:stylesheet> 

当这种转变被应用到提供XML文档

<hello> 
    <one> 
     <paragraph>p1</paragraph> 
    </one> 
</hello> 

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

<x:hello xmlns:x="some_new_namespace" xmlns:y="other_ns" y:an_attribute="a value for an_attribute"> 
    <one> 
     <paragraph>p1</paragraph> 
    </one> 
</x:hello>