betterCode() PHP 2025

La clase DOMNode

(PHP 5, PHP 7, PHP 8)

Sinopsis de la Clase

class DOMNode {
/* Constantes */
public const int DOCUMENT_POSITION_DISCONNECTED = 0x1;
public const int DOCUMENT_POSITION_PRECEDING = 0x2;
public const int DOCUMENT_POSITION_FOLLOWING = 0x4;
public const int DOCUMENT_POSITION_CONTAINS = 0x8;
public const int DOCUMENT_POSITION_CONTAINED_BY = 0x10;
/* Propiedades */
public readonly string $nodeName;
public readonly int $nodeType;
public readonly ?DOMNode $parentNode;
public readonly ?DOMElement $parentElement;
public readonly DOMNodeList $childNodes;
public readonly ?DOMNode $firstChild;
public readonly ?DOMNode $lastChild;
public readonly ?DOMNode $previousSibling;
public readonly ?DOMNode $nextSibling;
public readonly ?DOMNamedNodeMap $attributes;
public readonly bool $isConnected;
public readonly ?DOMDocument $ownerDocument;
public readonly ?string $namespaceURI;
public string $prefix;
public readonly ?string $localName;
public readonly ?string $baseURI;
/* Métodos */
public C14N(
    bool $exclusive = false,
    bool $withComments = false,
    ?array $xpath = null,
    ?array $nsPrefixes = null
): string|false
public C14NFile(
    string $uri,
    bool $exclusive = false,
    bool $withComments = false,
    ?array $xpath = null,
    ?array $nsPrefixes = null
): int|false
public cloneNode(bool $deep = false): DOMNode|false
public getLineNo(): int
public getRootNode(?array $options = null): DOMNode
public insertBefore(DOMNode $node, ?DOMNode $child = null): DOMNode|false
public isDefaultNamespace(string $namespaceURI): bool
public isEqualNode(?DOMNode $otherNode): bool
public isSameNode(DOMNode $otherNode): bool
public isSupported(string $feature, string $version): bool
public lookupPrefix(string $namespace): ?string
public normalize(): void
public replaceChild(DOMNode $node, DOMNode $child): DOMNode|false
public __sleep(): array
public __wakeup(): void
}

Constantes predefinidas

DOMNode::DOCUMENT_POSITION_DISCONNECTED
Definido cuando el otro nódo y el nódo de referencia no están en el mismo árbol.
DOMNode::DOCUMENT_POSITION_PRECEDING
Definido cuando el otro nódo precede al nódo de referencia.
DOMNode::DOCUMENT_POSITION_FOLLOWING
Definido cuando el otro nódo sigue al nódo de referencia.
DOMNode::DOCUMENT_POSITION_CONTAINS
Definido cuando el otro nódo es un ancestro del nódo de referencia.
DOMNode::DOCUMENT_POSITION_CONTAINED_BY
Definido cuando el otro nódo es un descendiente del nódo de referencia.
DOMNode::DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC
Definido cuando el resultado depende de un comportamiento específico de la implementación y puede no ser portable. Esto puede ocurrir con nódulos desconectados o con nódulos de atributos.

Propiedades

nodeName

Devuelve el nombre más preciso para el tipo de nódo actual.

nodeValue

El valor de este nódo, según su tipo. A diferencia de las especificaciones W3C, el valor del nódo de los nódulos DOMElement es igual a DOMNode::textContent en lugar de null.

nodeType

Recupera el tipo del nódo. Una de las constantes XML_*_NODE

parentNode

El padre de este nódo. Si este tipo de nódo no existe, esto devolverá null.

parentElement

El elemento padre de este elemento. Si no hay tal elemento, esto devuelve null.

childNodes

Un DOMNodeList que contiene todos los hijos de este nódo. Si no hay hijos, será un DOMNodeList vacío.

firstChild

El primer hijo de este nódo. Si no hay nódo de este tipo, devuelve null.

lastChild

El último hijo de este nódo. Si no hay nódo de este tipo, devuelve null.

previousSibling

El nódo que precede inmediatamente a este nódo. Si no hay nódo, devuelve null.

nextSibling

El nódo que sigue inmediatamente a este nódo. Si no hay nódo, devuelve null.

attributes

Un DOMNamedNodeMap que contiene los atributos de este nódo (si es un DOMElement) o null en caso contrario.

isConnected

Si el nódo está conectado a un documento o no.

ownerDocument

El objeto DOMDocument asociado con este nódo, o null si este nódo no tiene un documento asociado (p. ej., si está separado o es un DOMDocument).

namespaceURI

El espacio de nombres de la URL para este nódo, o null si no está especificado.

prefix

El prefijo del espacio de nombres de este nódo.

localName

Devuelve la parte local del nombre cualificado del nódo.

baseURI

La base de la URL absoluta del nódo, o null si la implementación no ha logrado obtener la URL absoluta.

textContent

El contenido textual de este nódo y sus descendientes.

Historial de cambios

Versión Descripción
8.4.0 El método DOMNode::compareDocumentPosition() ha sido añadido.
8.4.0 Las constantes DOMNode::DOCUMENT_POSITION_DISCONNECTED, DOMNode::DOCUMENT_POSITION_PRECEDING, DOMNode::DOCUMENT_POSITION_FOLLOWING, DOMNode::DOCUMENT_POSITION_CONTAINS, DOMNode::DOCUMENT_POSITION_CONTAINED_BY, y DOMNode::DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC han sido añadidas.
8.3.0 Los métodos DOMNode::contains() y DOMNode::isEqualNode() han sido añadidos.
8.3.0 Las propiedades DOMNode::$parentElement, y DOMNode::$isConnected han sido añadidas.
8.0.0 Los métodos no implementados DOMNode::compareDocumentPosition(), DOMNode::isEqualNode(), DOMNode::getFeature(), DOMNode::setUserData() y DOMNode::getUserData() han sido eliminados.

Notas

Nota:

La extensión DOM utiliza el codificado UTF-8. Utilice mb_convert_encoding(), UConverter::transcode(), o iconv() para manipular otros codificados.

Tabla de contenidos

add a note

User Contributed Notes 13 notes

up
43
marc at ermshaus dot org
16 years ago
It took me forever to find a mapping for the XML_*_NODE constants. So I thought, it'd be handy to paste it here:

1 XML_ELEMENT_NODE
2 XML_ATTRIBUTE_NODE
3 XML_TEXT_NODE
4 XML_CDATA_SECTION_NODE
5 XML_ENTITY_REFERENCE_NODE
6 XML_ENTITY_NODE
7 XML_PROCESSING_INSTRUCTION_NODE
8 XML_COMMENT_NODE
9 XML_DOCUMENT_NODE
10 XML_DOCUMENT_TYPE_NODE
11 XML_DOCUMENT_FRAGMENT_NODE
12 XML_NOTATION_NODE
up
23
David Rekowski
15 years ago
You cannot simply overwrite $textContent, to replace the text content of a DOMNode, as the missing readonly flag suggests. Instead you have to do something like this:

<?php

$node
->removeChild($node->firstChild);
$node->appendChild(new DOMText('new text content'));

?>

This example shows what happens:

<?php

$doc
= DOMDocument::loadXML('<node>old content</node>');
$node = $doc->getElementsByTagName('node')->item(0);
echo
"Content 1: ".$node->textContent."\n";

$node->textContent = 'new content';
echo
"Content 2: ".$node->textContent."\n";

$newText = new DOMText('new content');

$node->appendChild($newText);
echo
"Content 3: ".$node->textContent."\n";

$node->removeChild($node->firstChild);
$node->appendChild($newText);
echo
"Content 4: ".$node->textContent."\n";

?>

The output is:

Content 1: old content // starting content
Content 2: old content // trying to replace overwriting $node->textContent
Content 3: old contentnew content // simply appending the new text node
Content 4: new content // removing firstchild before appending the new text node

If you want to have a CDATA section, use this:

<?php
$doc
= DOMDocument::loadXML('<node>old content</node>');
$node = $doc->getElementsByTagName('node')->item(0);
$node->removeChild($node->firstChild);
$newText = $doc->createCDATASection('new cdata content');
$node->appendChild($newText);
echo
"Content withCDATA: ".$doc->saveXML($node)."\n";
?>
up
20
R. Studer
15 years ago
For clarification:
The assumingly 'discoverd' by previous posters and seemingly undocumented methods (.getElementsByTagName and .getAttribute) on this class (DOMNode) are in fact methods of the class DOMElement, which inherits from DOMNode.

See: http://www.php.net/manual/en/class.domelement.php
up
10
brian wildwoodassociates.info
16 years ago
This class has a getAttribute method.

Assume that a DOMNode object $ref contained an anchor taken out of a DOMNode List. Then

$url = $ref->getAttribute('href');

would isolate the url associated with the href part of the anchor.
up
6
alastair dot dallas at gmail dot com
14 years ago
The issues around mixed content took me some experimentation to remember, so I thought I'd add this note to save others time.

When your markup is something like: <div><p>First text.</p><ul><li><p>First bullet</p></li></ul></div>, you'll get XML_ELEMENT_NODEs that are quite regular. The <div> has children <p> and <ul> and the nodeValue for both <p>s yields the text you expect.

But when your markup is more like <p>This is <b>bold</b> and this is <i>italic</i>.</p>, you realize that the nodeValue for XML_ELEMENT_NODEs is not reliable. In this case, you need to look at the <p>'s child nodes. For this example, the <p> has children: #text, <b>, #text, <i>, #text.

In this example, the nodeValue of <b> and <i> is the same as their #text children. But you could have markup like: <p>This <b>is bold and <i>bold italic</i></b>, you see?</p>. In this case, you need to look at the children of <b>, which will be #text, <i>, because the nodeValue of <b> will not be sufficient.

XML_TEXT_NODEs have no children and are always named '#text'. Depending on how whitespace is handled, your tree may have "empty" #text nodes as children of <body> and elsewhere.

Attributes are nodes, but I had forgotten that they are not in the tree expressed by childNodes. Walking the full tree using childNodes will not visit any attribute nodes.
up
8
imranomar at gmail dot com
14 years ago
Just discovered that node->nodeValue strips out all the tags
up
5
Steve K
15 years ago
This class apparently also has a getElementsByTagName method.

I was able to confirm this by evaluating the output from DOMNodeList->item() against various tests with the is_a() function.
up
3
metanull
11 years ago
Yet another DOMNode to php array conversion function.
Other ones on this page are generating too "complex" arrays; this one should keep the array as tidy as possible.
Note: make sure to set LIBXML_NOBLANKS when calling DOMDocument::load, loadXML or loadHTML
See: http://be2.php.net/manual/en/libxml.constants.php
See: http://be2.php.net/manual/en/domdocument.loadxml.php

<?php
/**
* Returns an array representation of a DOMNode
* Note, make sure to use the LIBXML_NOBLANKS flag when loading XML into the DOMDocument
* @param DOMDocument $dom
* @param DOMNode $node
* @return array
*/
function nodeToArray( $dom, $node) {
if(!
is_a( $dom, 'DOMDocument' ) || !is_a( $node, 'DOMNode' )) {
return
false;
}
$array = false;
if( empty(
trim( $node->localName ))) {// Discard empty nodes
return false;
}
if(
XML_TEXT_NODE == $node->nodeType ) {
return
$node->nodeValue;
}
foreach (
$node->attributes as $attr) {
$array['@'.$attr->localName] = $attr->nodeValue;
}
foreach (
$node->childNodes as $childNode) {
if (
1 == $childNode->childNodes->length && XML_TEXT_NODE == $childNode->firstChild->nodeType ) {
$array[$childNode->localName] = $childNode->nodeValue;
} else {
if(
false !== ($a = self::nodeToArray( $dom, $childNode))) {
$array[$childNode->localName] = $a;
}
}
}
return
$array;
}
?>
up
3
pizarropablo at gmail dot com
11 years ago
In response to: alastair dot dallas at gmail dot com about "#text" nodes.
"#text" nodes appear when there are spaces or new lines between end tag and next initial tag.

Eg "<data><age>10</age>[SPACES]<other>20</other>[SPACES]</data>"

"data" childNodes has 4 childs:
- age = 10
- #text = spaces
- other = 20
- #text = spaces
up
2
matej dot golian at gmail dot com
12 years ago
Here is a little function that truncates a DomNode to a specified number of text characters. I use it to generate HTML excerpts for my blog entries.

<?php

function makehtmlexcerpt(DomNode $html, $excerptlength)
{
$remove = 0;
$htmllength = strlen(html_entity_decode($html->textContent, ENT_QUOTES, 'UTF-8'));
$truncate = $htmllength - $excerptlength;
if(
$htmllength > $excerptlength)
{
if(
$html->hasChildNodes())
{
$children = $html->childNodes;
for(
$counter = 0; $counter < $children->length; $counter ++)
{
$child = $children->item($children->length - ($counter + 1));
$childlength = strlen(html_entity_decode($child->textContent, ENT_QUOTES, 'UTF-8'));
if(
$childlength <= $truncate)
{
$remove ++;
$truncate = $truncate - $childlength;
}
else
{
$child = makehtmlexcerpt($child, $childlength - $truncate);
break;
}
}
if(
$remove != 0)
{
for(
$counter = 0; $counter < $remove; $counter ++)
{
$html->removeChild($html->lastChild);
}
}
}
else
{
if(
$html->nodeName == '#text')
{
$html->nodeValue = substr(html_entity_decode($html->nodeValue, ENT_QUOTES, 'UTF-8'), 0, $htmllength - $truncate);
}
}
}
return
$html;
}

?>
up
5
matt at lamplightdb dot co dot uk
16 years ago
And apparently also a setAttribute method too:

$node->setAttribute( 'attrName' , 'value' );
up
-1
Anonymous
7 years ago
It would be helpful if docs for concrete properties mentioned readonly status of some properties:
"
ownerDocument

The DOMDocument object associated with this node.

"
up
-1
zlk1214 at gmail dot com
9 years ago
A function that can set the inner HTML without encoding error. $html can be broken content such as "<a ID=id20>ssss"
function setInnerHTML($node, $html) {
removeChildren($node);
if (empty($html)) {
return;
}

$doc = $node->ownerDocument;
$htmlclip = new DOMDocument();
$htmlclip->loadHTML('<meta http-equiv="Content-Type" content="text/html;charset=utf-8"><div>' . $html . '</div>');
$clipNode = $doc->importNode($htmlclip->documentElement->lastChild->firstChild, true);
while ($item = $clipNode->firstChild) {
$node->appendChild($item);
}
}
To Top