Эти атрибуты являются особыми из-за их типа , а не из-за их имени .
идентификаторов в XML
Хотя атрибуты легко представить себе как name="value"
, а значение представляет собой простую строку, это не полная история - с атрибутами также связан тип атрибута .
Это легко понять, когда речь идет о схеме XML, поскольку схема XML поддерживает типы данных как для элементов XML, так и для атрибутов XML.Атрибуты XML определены как простые типа (например, xs: строка, xs: целое число, xs: dateTime, xs: anyURI).Обсуждаемые здесь атрибуты определяются с помощью встроенного типа данных xs:ID
(см. раздел 3.3.8 схемы XML, часть 2. Типы данных ).
<xs:element name="foo">
<xs:complexType>
...
<xs:attribute name="bar" type="xs:ID"/>
...
</xs:complexType>
</xs:element>
Хотя DTD donНе поддерживает богатые типы данных в XML-схеме, он поддерживает ограниченный набор типов атрибутов (который определен в разделе 3.3.1 XML 1.0 ).Обсуждаемые здесь атрибуты определены с типом атрибута из ID
.
<!ATTLIST foo bar ID #IMPLIED>
При использовании вышеуказанной схемы XML или DTD следующий элемент будет идентифицирован значением идентификатораиз «xyz».
<foo bar="xyz"/>
Не зная схемы XML или DTD, невозможно определить, что такое идентификатор, а что нет:
- Атрибуты с именем«id» не обязательно имеет атрибут типа идентификатора;и
- Атрибуты с именами, которые не являются "id", могут иметь тип атрибута ID!
Чтобы улучшить эту ситуацию, xml:id
был впоследствииизобретено (см. xml: id W3C Рекомендация ).Это атрибут, который всегда имеет одинаковый префикс и имя и предназначен для обработки в качестве атрибута с типом атрибута идентификатора.Однако, зависит ли это от используемого парсера, известно о xml:id
или нет.Поскольку многие синтаксические анализаторы были изначально написаны до того, как было определено xml:id
, это может не поддерживаться.
идентификаторов в Java
В Java getElementById()
находит элементы, просматриваядля атрибутов типа ID, а не для атрибутов с name для "id".
В приведенном выше примере getElementById("xyz")
вернет этот элемент foo
даже если имя атрибута в нем не «id» (при условии, что DOM знает, что bar
имеет тип атрибута ID).
Так как DOM узнаеткакой тип атрибута имеет атрибут?Существует три способа:
- Предоставить схему XML для анализатора ( пример )
- Предоставить DTD для анализатора
- Явно указатьDOM, который рассматривается как тип атрибута ID.
Третий вариант выполняется с помощью методов setIdAttribute()
или setIdAttributeNS()
или setIdAttributeNode()
в org.w3c.dom.Element
class .
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.
Этот третий подход полезен только в ситуацияхгде код, вызывающий getElementById()
, отделен от кода, создающего DOM.Если это был тот же код, то он уже нашел элемент для установки атрибута ID, поэтому вряд ли потребуется вызывать getElementById()
.
. Также имейте в виду, что эти методы не были в исходной спецификации DOM,getElementById
был введен в DOM уровня 2 .
идентификаторов в XPath
XPath в исходном вопросе дал результат, потому что он былсоответствует только атрибуту name .
Для соответствия значения типа атрибута ID необходимо использовать функцию XPath id
(это одна из Функции набора узлов из XPath 1.0 ):
id("xyz")
Если бы он был использован, XPath дал бы тот же результат, что и getElementById()
(то есть совпадение не найдено).
Идентификаторы в XML продолжаются
Следует выделить две важные особенности ID.
Во-первых, значения всех атрибутов типа атрибута ID должны быть уникальными для всего XML-документа . В следующем примере, если personId
и companyId
оба имеют атрибут типа идентификатора, было бы ошибкой добавить другую компанию с companyId
id24601, потому что это будет дубликат существующее значение идентификатора. Несмотря на то, что имена атрибутов разные, имеет значение тип атрибута .
<test1>
<person personId="id24600">...</person>
<person personId="id24601">...</person>
<company companyId="id12345">...</company>
<company companyId="id12346">...</company>
</test1>
Во-вторых, атрибуты определены для элементов , а не для всего документа XML. Поэтому атрибуты с одинаковыми именами атрибутов в разных элементах могут иметь разные свойства type type . В следующем примере XML-документа, если только alpha/@bar
имеет тип атрибута идентификатора (и никакого другого атрибута не было), getElementById("xyz")
вернет элемент, но getElementById("abc")
не будет (так как beta/@bar
не имеет атрибута типа ID). Кроме того, атрибут gamma/@bar
не может иметь то же значение, что и alpha/@bar
, это значение не учитывается в уникальности идентификаторов в документе XML, поскольку оно не имеет тип атрибута ID.
<test2>
<alpha bar="xyz"/>
<beta bar="abc"/>
<gamma bar="xyz"/>
</test2>