PHP 8.3.4 Released!

DOMDocument::getElementById

(PHP 5, PHP 7, PHP 8)

DOMDocument::getElementByIdProcura por um elemento com um determinado ID

Descrição

public DOMDocument::getElementById(string $elementId): ?DOMElement

Esta função é semelhante a DOMDocument::getElementsByTagName mas procura por um elemento com um determinado ID.

Para que esta função funcione, será necessário definir alguns atributos de ID com DOMElement::setIdAttribute ou um DTD que define um atributo como tipo ID. Neste último caso, será necessário validar o documento com DOMDocument::validate ou DOMDocument::$validateOnParse antes de usar esta função.

Parâmetros

elementId

O valor de ID único para um elemento.

Valor Retornado

Retorna o DOMElement ou null se o elemento não for encontrado.

Exemplos

Exemplo #1 DOMDocument::getElementById() Example

Os exemplos a seguir usam um arquivo book.xml que contém o seguinte:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE books [
  <!ELEMENT books   (book+)>
  <!ELEMENT book    (title, author+, xhtml:blurb?)>
  <!ELEMENT title   (#PCDATA)>
  <!ELEMENT blurb   (#PCDATA)>
  <!ELEMENT author  (#PCDATA)>
  <!ATTLIST books   xmlns        CDATA  #IMPLIED>
  <!ATTLIST books   xmlns:xhtml  CDATA  #IMPLIED>
  <!ATTLIST book    id           ID     #IMPLIED>
  <!ATTLIST author  email        CDATA  #IMPLIED>
]>
<?xml-stylesheet type="text/xsl" href="style.xsl"?>
<books xmlns="http://books.php/" xmlns:xhtml="http://www.w3.org/1999/xhtml">
  <book id="php-basics">
    <title>Princípios do PHP</title>
    <author email="jim.smith@basics.php">Jim Smith</author>
    <author email="jane.smith@basics.php">Jane Smith</author>
    <xhtml:blurb><![CDATA[
<p><em>Princípios do PHP</em> fornece uma introdução ao PHP.</p>
]]></xhtml:blurb>
  </book>
  <book id="php-advanced">
    <title>Programação PHP Avançada</title>
    <author email="jon.doe@advanced.php">Jon Doe</author>
  </book>
</books>
<?php

$doc
= new DomDocument;

// Precisamos validar nosso documento antes de referenciar o ID
$doc->validateOnParse = true;
$doc->Load('book.xml');

echo
"The element whose id is 'php-basics' is: " . $doc->getElementById('php-basics')->tagName . "\n";

?>

O exemplo acima produzirá:

The element whose id is 'php-basics' is: book

Veja Também

add a note

User Contributed Notes 10 notes

up
44
ed at edgiardina dot com
13 years ago
Please note that if your HTML does not contain a doctype declaration, then getElementById will always return null.
up
6
carl2088 at gmail dot com
14 years ago
From my experience, getElementById seem to work fine without any setups if you have loaded a HTML document. But in order for getElementById to work with a simple XML document that you've "constructed", you have to set up the id with "xml:" prefix and use setIdAttribute on the element you created or it won't work. See following example, hope this will save someone's frustration. If you have loaded the xml file, then all you have to make sure is the ID has a xml: prefix for the attribute. But if you start to append the XML document, don't forget to setIdAttribute on the id name or those elements or getElementById will return null when you try to find them.

<?php

/* test.xml
<?xml version="1.0" encoding="utf-8"?>
<root>
<child xml:id="id_xxxxxx" status="partial">
<sub_child>Some Data</sub_child>
</child>
</root>
*/

$xmlDom = new DOMDocument('1.0', 'utf-8');
$xmlDom->formatOutput = true; // we want a nice output

// create a root
$eltRoot = $xmlDom->createElement("root");
$xmlDom->appendChild($eltRoot);

$eltChild = $xmlDom->createElement("child");
$eltRoot->appendChild($eltChild);

// add a id attribute
$attr = $xmlDom->createAttribute("xml:id"); // needs xml prefix or getElementById won't work
$eltChild->appendChild($attr);

/// create the text node and append to the created element
$tNode = $xmlDom->createTextNode("id_8120528");
$attr->appendChild($tNode);
$eltChild->setIdAttribute("xml:id", true); // VERY IMPORT or getElementById won't work

// add a id attribute
$attr = $xmlDom->createAttribute("status");
$eltChild->appendChild($attr);

/// create the text node and append to the created element
$tNode = $xmlDom->createTextNode("partial");
$attr->appendChild($tNode);

// add a subchild
$eltSub = $xmlDom->createElement("sub_child");
$eltChild->appendChild($eltSub);

$tNode = $xmlDom->createTextNode("Some Data");
$eltSub->appendChild($tNode);

$id = null;
$id = $xmlDom->getElementById("id_8120528");

assert ($id != null);

$strId = $id->getAttribute("xml:id"); // bug? empty
$strStatus = $id->getAttribute("status"); // this works!

assert ($id !=null);

$xmlDom->save("./_data/test.xml");

$xmlDom->load("./_data/test.xml"); // reloading fixes the problem

$nodeRoot = $xmlDom->getElementsByTagName("root");
if (
$nodeRoot->length > 0) {
$eltRoot = $nodeRoot->item(0);
}

assert($eltRoot != null);

$id = null;
$id = $xmlDom->getElementById("id_8120528");

assert ($id != null);

$strId = $id->getAttribute("xml:id"); // this works now!
$strStatus = $id->getAttribute("status"); // this works!


?>
up
2
simon at somewhere dot com
17 years ago
SAVE YOURSELF A MAJOR HEADACHE AND A LOT OF SEARCHING THROUGH DOCUMENTATION -

Instead of using $object->setAttribute('id', 'id_name_here')
USE THIS: $object->setAttribute('xml:id', 'id_name_here')

Then, to get the node value: $domDocumentObject->getElementById('id_name_here');

The xml:id attribute should AUTOMATICALLY be defined!!

Woohoo! That was easy......
up
1
bart at mediawave dot nl
18 years ago
It seems getElementById works fine without setting validateOnParse to true. Which is nice since setting this to true caused some performance problems with my script.
up
3
paradox_haze at live dot de
14 years ago
Had some issues with getElementById() while searching for a specific element in a XHTML document.
I wrote a small function what was solving my problem:

<?php
function getElementById($id)
{
$xpath = new DOMXPath($this->domDocument);
return
$xpath->query("//*[@id='$id']")->item(0);
}
?>
up
1
Anonymous
18 years ago
If you're trying to use getElementById with a xml file validated on a xsd file you must first use the schemaValidate function or getElementById will return null
Example:

$dom = new DomDocument();
$dom->load("users.xml");
$dom->schemaValidate("users.xsd");

$curruser = $dom->getElementById($user->name);
up
2
Hoi
3 years ago
To set a hidden id that can be used by $dom->getElementById() apply setAttribute('id', true) as in the following example

$createItemNode = function ($data) use ($dom) {
$node = $dom->createElement("Item");
$node->setAttribute('id', $data->id);
$node->setAttribute('hed', $data->hed);
$node->setAttribute('run_time', $data->run_time);
$node->setAttribute('date', $data->date);

// Internally mark the id as 'xml:id' for getElementById to work. Adding xml:id manually to the tag will cause loadXML to throw an error DOMDocument: xml:id is not a NCName in Entity
$node->setIdAttribute('id', true);

return $node;
};

With $node->setIdAttribute('id', true), $dom->getElementById($id) will work

When you do $dom->saveXML(), the final doc will not contain any xml:id attribute.
up
0
Tangui dot Le-Pense at laposte dot net
17 years ago
Validating a document from a DTD so as to use getElementById is sometimes impossible (for example when the head and body elements are not included yet in a XHtml document : the validation failed).
Fortunately, xml:id is supported by this function :)
That may be useful.
http://www.w3.org/TR/xml-id/
up
-2
jonbarnett at gmail dot com
17 years ago
If your XML document does not have a DTD that defines the "id" attribute as an ID, then the easiest thing to do is to use XPath->query() to find an element that matches "//[@id='x']"
up
-2
guillaume dot crico at gmail dot com
15 years ago
You don't want to use "xml:id" ?
Here is the relaxNG trick (with a generic schema):
(tested with libxml 2.6.26)

<?php
$doc
= new DOMDocument();
$doc->load(...);

$rng = '
<grammar xmlns="http://relaxng.org/ns/structure/1.0" datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes">
<start>
<element>
<anyName/>
<ref name="anythingID"/>
</element>
</start>
<define name="anythingID">
<zeroOrMore>
<choice>
<element>
<anyName/>
<ref name="anythingID"/>
</element>
<attribute name="id">
<data type="ID"/>
</attribute>
<zeroOrMore>
<attribute><anyName/></attribute>
</zeroOrMore>
<text/>
</choice>
</zeroOrMore>
</define>
</grammar>
'
;

$doc->relaxNGValidateSource($rng);
var_dump($doc->getElementById('id1'));
?>


Note that ID values must be valid ones :
- integers do no work!
- @see http://www.w3.org/TR/REC-xml/#id
- => (Letter | '_' | ':') ( Letter | Digit | '.' | '-' | '_' | ':' | CombiningChar | Extender )*
To Top