未限定属性名的XML默认命名空间?

30
我正在尝试理解"XML 1.0(第三版)中的命名空间"对未限定属性命名空间的正确解释。

“未带前缀的属性名称的命名空间名称始终没有值。”

在同一部分中稍后又提到:

“默认命名空间声明中的属性值可以为空。在声明的范围内,这与不存在默认命名空间具有相同的效果。”

因此,如果我想为元素(及其子元素)声明默认命名空间,那么我是否还需要为驻留在该命名空间中的任何属性声明前缀-命名空间映射?
例如,在此示例中:
<parent xmlns="http://example.com/foo">
    <child attrib="value">text</child>
<parent>

我会将上面的定义解释为attrib的命名空间为空。
因此,如果我需要attribparent具有相同的命名空间,则不得不这样做吗?
<foo:parent xmlns:foo="http://example.com/foo">
    <foo:child foo:attrib="value">text</foo:child>
<foo:parent>

或这个?
<parent xmlns="http://example.com/foo" xmlns:foo="http://example.com/foo">
    <child foo:attrib="value">text</child>
<parent>

这对我来说似乎很愚蠢,因为它似乎违背了默认命名空间的目的。我希望我只是误解了规范。
4个回答

18

你说得对。属性不属于默认命名空间的理念是它们被认为存在于"元素命名空间"中,因此在这种情况下,<foo:child/> 被视为 @attrib 的'命名空间'。请注意,这只是概念上的;没有API或任何东西以这种方式引用属性命名空间。

之所以选择这个方案是因为多个元素可以具有相同名称但含义不同的属性,而传统的命名空间则是名称集合(因此不存在重复)。从某种意义上讲,它给命名空间提供了更多结构,而不是仅仅拥有一组扁平的名称。

你可以在Namespaces recommendation的一个非常旧的版本中阅读相关内容。

这个约定意味着每当你看到带前缀的属性时,它表示一些与文档中主要模式无关的“额外”信息。


谢谢。我有点困惑如何表示标签是上下文。如果“<foo:child />@attrib的'命名空间',那么我不需要添加其他前缀来提供命名空间。换句话说,它将是未限定的,这将被解释为在元素使用的任何命名空间中。这是正确的吗?这意味着我的第一个示例实际上是编写此内容的一种可行方式。 - mckamey
是的,惯例是使属性无名称空间,就像您的第一个示例一样。 "它将是未限定的,这将被解释为在元素使用的任何名称空间中" ... 这是想法,但请注意,属性将不会报告与元素相同的名称空间,或者元素作为“名称空间”。 它不会有任何名称空间 - 具有元素作为“名称空间”的属性只是一种约定。 - porges
8
好的,我现在明白了。通常,属性不会被分配明确的命名空间,因为它们属于元素的上下文,而该元素可能具有命名空间。这将像示例1一样编写。如果一个属性有一个特定的命名空间,通常它会在元素模式之外,并且应该像示例2或3那样编写,但通常不会是相同的命名空间。 - mckamey
你的解释比我说得更好 :) - porges

11

根据规范,您正确地认为第一个示例中 attrib 的命名空间为空。但是,在这里有一个可能不太明显的微妙之处。

请考虑规范中更深入的示例,其中一个元素具有两个具有相同名称的属性(一个带前缀,另一个没有前缀)。

<!-- This is OK, even though an element cannot have two attributes 
     with the same name -->
<x xmlns:n1="http://www.w3.org" 
   xmlns="http://www.w3.org" >
  <good a="1"     n1:a="2" />
</x>

这是合规的,因为这两个属性确实在两个不同的命名空间中:

  • n1:a 属于 http://www.w3.org 命名空间(这也是 good 的命名空间)
  • a 被视为属于一个无法访问的命名空间 http://wwww.w3.org > good(与 good 的命名空间不同)。

请注意,http://wwww.w3.org > good 命名空间不存在;例如,您不能使用XPath查询此命名空间中的属性。如果询问 namespace-uri(\\good\a),则为空。为了使元素命名空间的概念具体化,我想出了一个命名空间,其中包括元素命名空间和名称以及分隔符(在属性值中未转义的 > 无效)。

现在,与其说这两个属性位于两个不同的命名空间中,不如说它们属于两个不同的命名空间分区

  • n1:a 属性属于全局属性分区(http://www.w3.org
  • good 元素属于所有元素类型分区(也是 http://www.w3.org
  • a 属于 good 的每个元素类型分区(即 http://wwww.w3.org > good)。

以下是 Porges 链接的规范的相关部分:

  

A.2 XML Namespace Partitions

     

为了支持使限定和非限定名称在达到其预期目的方面都有用的目标,我们将出现在 XML 命名空间中的名称标识为属于几个不同的不相交传统(即集合结构)命名空间之一,称为命名空间分区。分区如下:

     

所有元素类型分区 XML 命名空间中的所有元素类型均出现在此分区中。每个元素类型都有唯一的本地部分;命名空间名称和本地部分的组合唯一标识元素类型。

     

全局属性分区 此分区包含在该命名空间中定义为全局的所有属性的名称。全局属性的唯一必要特征是其名称在全局属性分区中是唯一的。本规范不断言这些属性的正确使用方式。命名空间名称和属性名称的组合唯一标识全局属性。

     

每个元素类型分区 所有元素类型分区中的每种类型都有一个关联的命名空间,其中出现为该元素提供的非限定属性的名称。这是传统命名空间,因为 XML 1.0 禁止在元素上出现重复的属性名称。属性名称与元素类型和命名空间名称的组合将唯一标识每个非限定属性。

     

在符合本规范的 XML 文档中,所有限定(带前缀)属性的名称都分配给全局属性分区,而所有非限定属性的名称都分配给相应的每个元素类型分区。


谢谢,@Raghu-Dodda。这种微妙之处是XML过于复杂,导致不必要的错误的一个很好的例子。 - mckamey
非常感谢。很高兴知道您示例中的前缀属性和无前缀属性都属于同一命名空间,但属于不同的命名空间分区。 - doABarrelRoll721
我们可以说,如果属性是通过 <xsd:attribute> 定义的(参见此示例),它将进入全局属性分区,因此需要加前缀吗? - dma_k

2
您对规范的解释是正确的。在您引用的命名空间规范的第6.2节的第二段中,还给出了某种合理性解释:
“未加前缀的属性的解释取决于它们所出现的元素。”
但我也很想了解为什么选择了这种特定的行为。

2
那个额外的段落似乎暗示着有关该主题的更多信息,但我似乎找不到它。我对写下那段话的W3C编辑的问题是:“在给定出现的元素上,如何解释未加前缀的属性?” - mckamey
1
它由读取XML文档的程序解释。它不在建议的范围之内。您可以根据自己的意愿进行解释。因此,XML词汇表的创建者决定每个元素中属性的含义。 - Ludovic Kuty

1

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接