选择具有默认命名空间的节点

时间:2009-06-17 18:53:49

标签: xslt xpath namespaces

我有一个XML文档,其中包含许多不同的命名空间和要验证的模式。模式要求所有元素都是“合格的”,我认为这意味着它们需要具有完整的QNames而没有空命名空间。

然而,这个巨大的XML文档中的一些元素只使用默认命名空间,在本文档的情况下是空白。从本质上讲,它们无法通过模式进行验证。

我正在尝试编写一个XSLT,它将选择没有命名空间的节点,并为它们分配一个与其他节点具有相同前缀的特定节点。例如:

<x:doc xmlns:x="http://thisns.com/">
  <x:node @x:property="true">
     this part passes validation
  </x:node>
  <node property="false">
     this part does not pass validation
  </node>
</x:doc>

我尝试将xmlns="http://thisns.com/"添加到文档的根节点,但这与架构验证程序不一致。关于如何使这项工作的任何想法?

谢谢!

1 个答案:

答案 0 :(得分:3)

<!-- Identity transform by default -->
<xsl:template match="node() | @*">
  <xsl:copy>
    <xsl:apply-templates select="node() | @*"/>
  </xsl:copy>
</xsl:template>
<!-- Override identity transform for elements with blank namespace -->
<xsl:template match="*[namespace-uri() = '']">    
  <xsl:element name="{local-name()}" namespace="http://thisns.com/">
    <xsl:apply-templates select="node() | @*"/>
  </xsl:element>
</xsl:template>
<!-- Override identity transform for attributes with blank namespace -->
<xsl:template match="@*[namespace-uri() = '']">
  <xsl:attribute name="{local-name()}" namespace="http://thisns.com/"><xsl:value-of  select="."/></xsl:attribute>
</xsl:template>

这将得到类似于:

的结果
<x:doc xmlns:x="http://thisns.com/">
  <x:node x:property="true">
    this part passes validation
  </x:node>
  <node xp_0:property="false" xmlns="http://thisns.com/" xmlns:xp_0="http://thisns.com/">
     this part does not pass validation
  </node>
</x:doc>

注意第二个&lt;节点&gt;仍然没有名称空间前缀,但由于xmlns =属性,它现在被认为是同一名称空间的一部分。