Estos atributos son especiales debido a su tipo y no a causa de su nombre.
ID en XML
Aunque es fácil pensar en atributos como name="value"
con el valor está siendo una cadena simple, que no es la historia completa - también hay un tipo atributo asociado con atributos.
Esto es fácil de apreciar cuando se trata de un esquema XML, ya que XML Schema admite tipos de datos para los elementos XML y los atributos XML. Los atributos XML se definen como de un tipo simple (por ejemplo, xs: string, xs: integer, xs: dateTime, xs: anyURI). Los atributos que se tratan aquí se definen con el tipo de datos incorporado xs:ID
(consulte section 3.3.8 of the XML Schema Part 2: Datatypes).
<xs:element name="foo">
<xs:complexType>
...
<xs:attribute name="bar" type="xs:ID"/>
...
</xs:complexType>
</xs:element>
Aunque DTD no son compatibles con los tipos de datos ricos en esquemas XML, soporta un conjunto limitado de tipos de atributos (que se define en section 3.3.1 of XML 1.0). Los atributos que se tratan aquí se definen con un tipo de atributo de ID
.
<!ATTLIST foo bar ID #IMPLIED>
ya sea con el esquema XML encima o DTD, el elemento siguiente será identificado por el valor de ID de "xyz".
<foo bar="xyz"/>
Sin conocer el esquema XML o DTD, no hay manera de saber lo que es un ID y lo que no se:
- atributos con el nombre de "id" no necesariamente tienen un tipo de atributo de ID; y
- ¡Los atributos con nombres que no son "id" pueden tener un tipo de atributo de ID!
Para mejorar esta situación, se inventó posteriormente el xml:id
(ver xml:id W3C Recommendation). Este es un atributo que siempre tiene el mismo prefijo y nombre, y está destinado a tratarse como un atributo con tipo de atributo de ID. Sin embargo, si lo hace dependerá de que el analizador utilizado sea consciente de xml:id
o no. Dado que muchos analizadores sintácticos se escribieron inicialmente antes de que se definiera el xml:id
, es posible que no sea compatible.
identificadores en Java
En Java, getElementById()
encuentra elementos mediante la búsqueda de atributos de tipo ID, no para los atributos con el nombre de "id".
En el ejemplo anterior, getElementById("xyz")
volverá ese elemento foo
, aunque el nombre del atributo en él no es "id" (suponiendo que el DOM sabe que bar
tiene un tipo de atributo de ID).
Entonces, ¿cómo sabe el DOM qué atributo tipo tiene un atributo? Hay tres maneras:
- proporcionar un esquema XML con el analizador (example)
- Proporcionar una DTD para el analizador
- indicar explícitamente a la DOM que se trata como un tipo de atributo de ID.
La tercera opción se realiza utilizando los setIdAttribute()
o setIdAttributeNS()
o setIdAttributeNode()
métodos en el 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");
Esto tiene que hacerse para cada nodo de elemento que tenga uno de estos tipos de atributos en ellos. No existe un método simple incorporado para hacer que todas las apariciones de atributos con un nombre de pila (por ejemplo, "id") sean de tipo de atributo ID.
Este tercer enfoque sólo es útil en situaciones donde el código llamando a la getElementById()
será independiente de que la creación de la DOM. Si era el mismo código, ya ha encontrado el elemento para establecer el atributo ID por lo que es poco probable que necesite llamar al getElementById()
.
Además, tenga en cuenta que esos métodos no estaban en la especificación DOM original. El getElementById
se introdujo en DOM level 2.
ID en XPath
El XPath en la pregunta original dio resultado, ya que sólo se pongan en venta el atributo de nombre .
para que coincida con el tipo valores de ID de atributos, la función XPath id
necesita ser utilizado (que es uno de los Node Set Functions from XPath 1.0):
id("xyz")
Si ese hubiera sido utilizado, el XPath habría dado el mismo resultado que getElementById()
(es decir, no se encontraron coincidencias).
ID en XML continuaron
Dos características importantes de ID deben ser resaltados.
En primer lugar, los valores de todos los atributos de tipo de atributo ID debe ser única para todo el documento XML. En el siguiente ejemplo, si personId
y companyId
tienen atributo tipo de ID, sería un error agregar otra compañía con companyId
de id24601, porque será un duplicado de un valor de ID existente. A pesar de que los nombres de los atributos son diferentes, es el tipo de atributo que importa.
<test1>
<person personId="id24600">...</person>
<person personId="id24601">...</person>
<company companyId="id12345">...</company>
<company companyId="id12346">...</company>
</test1>
En segundo lugar, los atributos se definen en los elementos en lugar de todo el documento XML. Por lo tanto, los atributos con el mismo nombre de atributo en diferentes elementos pueden tener diferentes propiedades de de tipo de atributo. En el siguiente documento XML de ejemplo, aunque sólo sea alpha/@bar
tiene un tipo de atributo de Identificación (y ningún otro atributo era), getElementById("xyz")
volverá un elemento, pero no lo hará getElementById("abc")
(ya que no es beta/@bar
de tipo de atributo ID). Además, no es un error que el atributo gamma/@bar
tenga el mismo valor que alpha/@bar
, ese valor no se considera en la exclusividad de los ID en el documento XML porque no es de ID de tipo de atributo.
<test2>
<alpha bar="xyz"/>
<beta bar="abc"/>
<gamma bar="xyz"/>
</test2>
+1 respuesta Niza! Aprendí algo nuevo hoy. –
Desafortunadamente, el enlace al ejemplo del esquema ya está muerto. – ferkulat