这些属性之所以特殊,是因为它们的类型,而不是因为它们的名称。
XML 中的 ID
虽然很容易将属性视为值是一个简单的字符串,但这并不是完整的故事 - 还有一个与属性关联的属性类型。name="value"
当涉及 XML 架构时,这很容易理解,因为 XML 架构支持 XML 元素和 XML 属性的数据类型。XML 属性被定义为简单类型(例如 xs:string、xs:integer、xs:dateTime、xs:anyURI)。此处讨论的属性是使用内置数据类型定义的(请参阅 XML 架构第 2 部分:数据类型的第 3.3.8 节)。xs:ID
<xs:element name="foo">
<xs:complexType>
...
<xs:attribute name="bar" type="xs:ID"/>
...
</xs:complexType>
</xs:element>
尽管 DTD 不支持 XML 架构中的丰富数据类型,但它确实支持一组有限的属性类型(在 XML 1.0 的第 3.3.1 节中定义)。此处讨论的属性是使用 属性类型 定义的。ID
<!ATTLIST foo bar ID #IMPLIED>
使用上述 XML 架构或 DTD,以下元素将由 ID 值“xyz”标识。
<foo bar="xyz"/>
如果不知道 XML 架构或 DTD,就无法分辨什么是 ID,什么不是:
- 名称为“id”的属性不一定具有 ID 的属性类型;和
- 名称不是“id”的属性可能具有 ID 的属性类型!
为了改善这种情况,随后发明了 (请参阅 xml:id W3C 建议)。这是一个始终具有相同的前缀和名称的属性,旨在被视为属性类型为 ID 的属性。但是,它是否这样做将取决于所使用的解析器是否知道。由于许多解析器最初是在定义之前编写的,因此可能不受支持。xml:id
xml:id
xml:id
爪哇中的 ID
在 Java 中,通过查找 ID 类型的属性来查找元素,而不是通过查找名称为“id”的属性来查找元素。getElementById()
在上面的示例中,将返回该元素,即使其上的属性名称不是“id”(假设 DOM 知道它具有 ID 的属性类型)。getElementById("xyz")
foo
bar
那么 DOM 如何知道属性具有什么属性类型呢?有三种方法:
- 向分析器提供 XML 架构(示例)
- 向解析器提供 DTD
- 向 DOM 显式指示它被视为 ID 的属性类型。
第三个选项是使用 org.w3c.dom.Element
类上的 or 或 方法完成的。setIdAttribute()
setIdAttributeNS()
setIdAttributeNode()
Document doc;
Element fooElem;
doc = ...; // load XML document instance
fooElem = ...; // locate the element node "foo" in doc
fooElem.setIdAttribute("bar", true); // without this, 'found' would be null
Element found = doc.getElementById("xyz");
必须为具有这些类型的属性之一的每个元素节点执行此操作。没有简单的内置方法可以使所有具有给定名称(例如“id”)的属性都属于属性类型ID。
第三种方法仅在调用 的代码与创建 DOM 的代码分开的情况下有用。如果它是相同的代码,则它已经找到了用于设置 ID 属性的元素,因此不太可能需要调用 。getElementById()
getElementById()
另外,请注意,这些方法不在原始 DOM 规范中。是在 DOM 级别 2 中引入的。getElementById
XPath 中的 ID
原始问题中的 XPath 给出了一个结果,因为它只与属性名称匹配。
要匹配属性类型 ID 值,需要使用 XPath 函数(它是 XPath 1.0 中的节点集函数之一):id
id("xyz")
如果使用了该方法,XPath 将给出与(即未找到匹配项)相同的结果。getElementById()
XML 中的 ID(续)
应突出显示 ID 的两个重要功能。
首先,属性类型 ID 的所有属性的值对于整个 XML 文档必须是唯一的。在以下示例中,如果并且两者都具有 ID 的属性类型,则添加另一个 id24601 的公司将是错误的,因为它将是现有 ID 值的副本。即使属性名称不同,重要的是属性类型。personId
companyId
companyId
<test1>
<person personId="id24600">...</person>
<person personId="id24601">...</person>
<company companyId="id12345">...</company>
<company companyId="id12346">...</company>
</test1>
其次,属性是在元素上定义的,而不是在整个 XML 文档上定义的。因此,在不同元素上具有相同属性名称的属性可能具有不同的属性类型属性。在下面的示例 XML 文档中,如果只有属性类型为 ID(并且没有其他属性),将返回一个元素,但不会返回(因为 不是属性类型 ID)。此外,属性具有与 相同的值也不是错误,该值在 XML 文档中 ID 的唯一性中不被考虑,因为它不是属性类型 ID。alpha/@bar
getElementById("xyz")
getElementById("abc")
beta/@bar
gamma/@bar
alpha/@bar
<test2>
<alpha bar="xyz"/>
<beta bar="abc"/>
<gamma bar="xyz"/>
</test2>