1

我有一个 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”的属性已经被神奇地删除了。为元素添加命名空间

我也有多个 xmlns:???在我想保留的 foo 中。

4

1 回答 1

0

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

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

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

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

您的预期结果文件不清楚。它还应该具有命名空间前缀 和 的命名xx空间B定义C。我还假设您的命名空间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">. 因此,您需要为输入文档的默认命名空间定义命名空间前缀,并在引用这些元素时使用该前缀,例如在matchandselect属性中。另请注意,因此,命名空间 URIhttp://www.isotc211.org/2005/gmd在结果文档中定义了两次 - 使用前缀gmd和作为默认命名空间。如果这让您感到困扰,您可以向元素添加exclude-result-prefixes="gmd"属性。<xsl:stylesheet>作为副作用,这可能会导致您的默认命名空间定义出现在文档的后面而不是根元素中,但这只是视觉上的差异,底层功能保持不变。

于 2012-12-11T23:31:24.247 回答