La classe DOMNode

(PHP 5, PHP 7, PHP 8)

Synopsis de la classe

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;
/* Propriétés */
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éthodes */
public function appendChild(DOMNode $node): DOMNode|false
public function C14N(
    bool $exclusive = false,
    bool $withComments = false,
    ?array $xpath = null,
    ?array $nsPrefixes = null
): string|false
public function C14NFile(
    string $uri,
    bool $exclusive = false,
    bool $withComments = false,
    ?array $xpath = null,
    ?array $nsPrefixes = null
): int|false
public function cloneNode(bool $deep = false): DOMNode|false
public function compareDocumentPosition(DOMNode $other): int
public function contains(DOMNode|DOMNameSpaceNode|null $other): bool
public function getLineNo(): int
public function getNodePath(): ?string
public function getRootNode(?array $options = null): DOMNode
public function hasAttributes(): bool
public function hasChildNodes(): bool
public function insertBefore(DOMNode $node, ?DOMNode $child = null): DOMNode|false
public function isDefaultNamespace(string $namespace): bool
public function isEqualNode(?DOMNode $otherNode): bool
public function isSameNode(DOMNode $otherNode): bool
public function isSupported(string $feature, string $version): bool
public function lookupNamespaceURI(?string $prefix): ?string
public function lookupPrefix(string $namespace): ?string
public function normalize(): void
public function removeChild(DOMNode $child): DOMNode|false
public function replaceChild(DOMNode $node, DOMNode $child): DOMNode|false
public function __sleep(): array
public function __wakeup(): void
}

Constantes pré-définies

DOMNode::DOCUMENT_POSITION_DISCONNECTED
DĂ©fini lorsque l'autre nƓud et le nƓud de rĂ©fĂ©rence ne sont pas dans le mĂȘme arbre.
DOMNode::DOCUMENT_POSITION_PRECEDING
DĂ©fini lorsque l'autre nƓud prĂ©cĂšde le nƓud de rĂ©fĂ©rence.
DOMNode::DOCUMENT_POSITION_FOLLOWING
DĂ©fini lorsque l'autre nƓud suit le nƓud de rĂ©fĂ©rence.
DOMNode::DOCUMENT_POSITION_CONTAINS
DĂ©fini lorsque l'autre nƓud est un ancĂȘtre du nƓud de rĂ©fĂ©rence.
DOMNode::DOCUMENT_POSITION_CONTAINED_BY
DĂ©fini lorsque l'autre nƓud est un descendant du nƓud de rĂ©fĂ©rence.
DOMNode::DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC
DĂ©fini lorsque le rĂ©sultat dĂ©pend d'un comportement spĂ©cifique Ă  l'implĂ©mentation et peut ne pas ĂȘtre portable. Cela peut se produire avec des nƓuds dĂ©connectĂ©s ou avec des nƓuds attributs.

Propriétés

nodeName

Retourne le nom, le plus prĂ©cis, pour le type de nƓud courant

nodeValue

La valeur de ce nƓud, suivant son type. Contrairement aux spĂ©cifications W3C, la valeur du nƓud des nƓuds DOMElement est Ă©gale Ă  DOMNode::textContent au lieu de null.

nodeType

RĂ©cupĂšre le type du nƓud. Une des constantes XML_*_NODE

parentNode

Le parent de ce nƓud. Si ce type de nƓud n'existe pas, ceci retournera null.

parentElement

L'élément parent de cet élément. S'il n'y a pas de tel élément, ceci retourne null.

childNodes

Un DOMNodeList qui contient tous les enfants de ce nƓud. S'il n'y a aucun enfant, ce sera un DOMNodeList vide.

firstChild

Le premier enfant de ce nƓud. S'il n'y a aucun nƓud de ce type, retourne null.

lastChild

Le dernier enfant de ce nƓud. S'il n'y a aucun nƓud de ce type, retourne null.

previousSibling

Le nƓud prĂ©cĂ©dant immĂ©diatement ce nƓud. S'il n'y a aucun nƓud, retourne null.

nextSibling

Le nƓud suivant immĂ©diatement ce nƓud. S'il n'y a aucun nƓud, retourne null.

attributes

Un DOMNamedNodeMap contenant les attributs de ce nƓud (si c'est un DOMElement) ou null sinon.

isConnected

Si le nƓud est connectĂ© Ă  un document ou non

ownerDocument

L'objet DOMDocument associĂ© avec ce nƓud, ou null si ce nƓud n'a pas de document associĂ© (par exemple, s'il est dĂ©tachĂ©, ou s'il s'agit d'un DOMDocument).

namespaceURI

L'URI du namespace de ce nƓud, ou null s'il n'est pas spĂ©cifiĂ©.

prefix

Le prĂ©fixe du namespace de ce nƓud.

localName

Retourne la partie locale du nom qualifiĂ© du nƓud.

baseURI

L'URI de base absolu du nƓud, ou null si l'implĂ©mentation n'a pas rĂ©ussi Ă  obtenir un URI absolu.

textContent

Le contenu textuel de ce nƓud et de ses descendants.

Historique

Version Description
8.4.0 La méthode DOMNode::compareDocumentPosition() a été ajoutée.
8.4.0 Les constantes DOMNode::DOCUMENT_POSITION_DISCONNECTED, DOMNode::DOCUMENT_POSITION_PRECEDING, DOMNode::DOCUMENT_POSITION_FOLLOWING, DOMNode::DOCUMENT_POSITION_CONTAINS, DOMNode::DOCUMENT_POSITION_CONTAINED_BY, et DOMNode::DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC ont été ajoutées.
8.3.0 Les méthodes DOMNode::contains() et DOMNode::isEqualNode() ont été ajoutées.
8.3.0 Les propriétés DOMNode::$parentElement, et DOMNode::$isConnected ont été ajoutées.
8.0.0 Les méthodes non implémentées DOMNode::compareDocumentPosition(), DOMNode::isEqualNode(), DOMNode::getFeature(), DOMNode::setUserData() et DOMNode::getUserData() ont été supprimées.

Notes

Note: L'extension DOM utilise l'encodage UTF-8. Utilisez mb_convert_encoding(), UConverter::transcode(), ou iconv() pour manipuler d'autres encodages.

Sommaire

add a note

User Contributed Notes 13 notes

up
43
marc at ermshaus dot org ¶
17 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 ¶
16 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 ¶
16 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 ¶
17 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
4
pizarropablo at gmail dot com ¶
12 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
8
imranomar at gmail dot com ¶
15 years ago
Just discovered that node->nodeValue strips out all the tags
up
5
Steve K ¶
16 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
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 ¶
17 years ago
And apparently also a setAttribute method too:

$node->setAttribute( 'attrName' , 'value' );
up
-1
Anonymous ¶
8 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 ¶
10 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);
    }
}