【问题标题】:Adding a variety of namespaces to elements为元素添加各种命名空间
【发布时间】:2012-11-25 22:03:54
【问题描述】:

我有一个 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 中。

【问题讨论】:

  • 没有命名空间“A”声明。如果您声明不排除任何前缀(),那么即使是未使用的前缀也应该输出。

标签: xslt add xml-namespaces


【解决方案1】:

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

【讨论】:

  • 感谢您的回复!然而,我被叫走了几天,现在无法尝试。不过,我会及时通知您。
  • 所以现在我回来了,我有时间查看您的答案。我已经阅读了 W3C 在他们的网站上关于 Namspaces 的信息,这真的很有帮助,非常感谢您指出这一点。我现在知道默认命名空间和“设置”命名空间之间的区别。我想我一直在错误的地方寻找解决问题的方法。
  • 问题是数据在网站上以 html 格式显示。使用来自具有默认命名空间的 xml 的输入创建的 Html 与使用具有“设置”命名空间的 xml 创建的不同。由于 w3c 没有说它们之间存在真正的区别,我认为这根本不是我应该担心的命名空间。这是 xslt
猜你喜欢
  • 2010-09-13
  • 1970-01-01
  • 2019-11-17
  • 2017-11-27
  • 1970-01-01
  • 2011-02-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多