向元素添加各种命名空间

时间:2012-12-07 17:22:14

标签: xslt add xml-namespaces

我有一个xml文档,其中一些元素具有命名空间而其他元素则没有。所有这些都需要命名空间,有些是相同的。这些元素具有我想要保留的属性。

xml:

<foo xmlns:gml="http://www.opengis.net/gml" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:gco="http://www.isotc211.org/2005/gco" xsi:schemaLocation="http://www.isotc211.org/2005/gmd http://schemas.opengis.net/iso/19139/20060504/gmd/gmd.xsd" xmlns="http://www.isotc211.org/2005/gmd">
<bar y="2">
<baz z="3"/></bar>
<a-special-element n="8"/>
<another-special-element k="8"/>
</foo>

和xslt:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"><xsl:template match="*">
    <xsl:element name="{local-name()}" namespace="A" >
        <xsl:copy-of select="attribute::*"/>
        <xsl:apply-templates />
    </xsl:element>
</xsl:template>

<xsl:template match="foo">
    <xx:foo xmlns:xx="xx">
        <xsl:apply-templates/>
    </xx:foo>
</xsl:template>

<xsl:template match="a-special-element">
    <B:a-special-element xmlns:B="B">
        <xsl:apply-templates/>
    </B:a-special-element>
</xsl:template>

<xsl:template match="another-special-element">
    <C:a-special-element xmlns:C="C">
        <xsl:apply-templates/>
    </C:another-special-element>
</xsl:template>

</xsl:stylesheet>

这是我想要的输出:

<xx:foo xmlns:gml="http://www.opengis.net/gml" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:gco="http://www.isotc211.org/2005/gco" xsi:schemaLocation="http://www.isotc211.org/2005/gmd http://schemas.opengis.net/iso/19139/20060504/gmd/gmd.xsd" xmlns="http://www.isotc211.org/2005/gmd">    <bar y="2">
    <baz z="3"/>
</bar>
<B:a-special-element n="8"/>
<C:another-special-element k="4"/>

</xx:foo>

我检查了这个帖子,但是“a-special-element”的属性被神奇地删除了。 Add a namespace to elements

我还有多个xmlns:???在我要保留的foo中。

1 个答案:

答案 0 :(得分:0)

首先:命名空间是XML中的基本概念。如果您不熟悉命名空间,请花些时间学习和理解它们。

  

我有一个xml文档,其中一些元素具有命名空间和   其他人没有。

实际上,在您的代码示例中,所有元素都属于命名空间。

根元素中的代码xmlns="http://www.isotc211.org/2005/gmd"定义了一个URI为"http://www.isotc211.org/2005/gmd"的默认命名空间。因此,如果元素名称没有名称空间前缀,则此元素及其后代属于此默认名称空间。如果元素使用默认命名空间,则很容易忘记元素在某个命名空间中,因为没有命名空间前缀。请注意,默认命名空间不适用于属性,仅适用于元素。

您的预期结果文件不清楚。它还应该具有名称空间前缀xxBC的名称空间定义。我还假设您的命名空间A与使用预期结果文档的默认命名空间相同。

无论如何,鉴于此输入:

<foo xmlns:gml="http://www.opengis.net/gml"
     xmlns:xlink="http://www.w3.org/1999/xlink"
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xmlns:gco="http://www.isotc211.org/2005/gco"
     xmlns="http://www.isotc211.org/2005/gmd"
     xsi:schemaLocation="http://www.isotc211.org/2005/gmd http://schemas.opengis.net/iso/19139/20060504/gmd/gmd.xsd"
     >
    <bar y="2">
        <baz z="3"/>
    </bar>
    <a-special-element n="8"/>
    <another-special-element k="8"/>
</foo>

此XSLT代码:

<xsl:stylesheet version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:gml="http://www.opengis.net/gml"
    xmlns:xlink="http://www.w3.org/1999/xlink"
    xmlns:gco="http://www.isotc211.org/2005/gco"
    xmlns:gmd="http://www.isotc211.org/2005/gmd"
    xmlns="http://www.isotc211.org/2005/gmd"
    xmlns:B="B"
    xmlns:C="C"
    xmlns:xx="xx"
    >

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

<xsl:template match="*">
    <xsl:element name="{local-name()}">
        <xsl:apply-templates select="node() | @*"/>
    </xsl:element>
</xsl:template>

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

<xsl:template match="gmd:a-special-element">
    <B:a-special-element>
        <xsl:apply-templates select="node() | @*"/>
    </B:a-special-element>
</xsl:template>

<xsl:template match="gmd:another-special-element">
    <C:another-special-element>
        <xsl:apply-templates select="node() | @*"/>
    </C:another-special-element>
</xsl:template>

</xsl:stylesheet>

会产生此输出:

<xx:foo xmlns:xx="xx" 
        xmlns:gml="http://www.opengis.net/gml" 
        xmlns:xlink="http://www.w3.org/1999/xlink" 
        xmlns:gco="http://www.isotc211.org/2005/gco" 
        xmlns:gmd="http://www.isotc211.org/2005/gmd" 
        xmlns="http://www.isotc211.org/2005/gmd" 
        xmlns:B="B" 
        xmlns:C="C" 
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
        xsi:schemaLocation="http://www.isotc211.org/2005/gmd http://schemas.opengis.net/iso/19139/20060504/gmd/gmd.xsd"
        >
    <bar y="2">
        <baz z="3"/>
    </bar>
    <B:a-special-element n="8"/>
    <C:another-special-element k="8"/>
</xx:foo>

注意如何使用身份模板递归复制输入文档的内容,这是一种常用且有用的技术。

请注意,XSLT文档的默认命名空间不适用于 <xsl:template match="ELEMENT-NAME">中使用的元素名称。因此,您需要为输入文档的默认命名空间定义名称空间前缀,并在引用这些元素时使用该前缀,例如在matchselect属性中。另请注意,因此,命名空间URI http://www.isotc211.org/2005/gmd在结果文档中定义了两次 - 前缀为gmd并作为默认命名空间。如果这让您感到困扰,可以将exclude-result-prefixes="gmd"属性添加到<xsl:stylesheet>元素中。作为副作用,这可能导致您的默认命名空间定义出现在文档的后面而不是根元素中,但这只是一个视觉差异,底层功能保持不变。