Browse DevX
Sign up for e-mail newsletters from DevX


Accessing and Manipulating the DOM with PHP : Page 2

Discover how to create a DOM tree from scratch or modify an existing DOM tree using PHP 5.




Building the Right Environment to Support AI, Machine Learning and Deep Learning

Browsing a DOM Tree Recursively

Because of the structure of XML, where tags either contain other tags (branches of the tree) or are leaf tags containing no child tags, you can browse an entire tree or subtree recursively by starting with any node, and following each child branch to the ending leaf nodes. The following example browses any XML subtree given a starting root node ($node), and lists the name and value of each encountered node.

function getNodesInfo($node) { if ($node->hasChildNodes()) { $subNodes = $node->childNodes; foreach ($subNodes as $subNode) { if (($subNode->nodeType != 3) || (($subNode->nodeType == 3) && (strlen(trim($subNode->wholeText))>=1))) { echo "Node name: ".$subNode->nodeName."\n"; echo "Node value: ".$subNode->nodeValue."\n"; } getNodesInfo($subNode); } } }

The preceding example removes any empty text nodes to clean up the output using this conditional test:

if (($subNode->nodeType != 3) || (($subNode->nodeType == 3) && (strlen(trim($subNode->wholeText))>=1)))

The preceding code checks to see whether the node being processed is either a non-text node (nodeType != 3) or a text node whose text is not empty. Alternatively, you could set the predefined preserveWhiteSpace property, which removes redundant white space, to FALSE. By default, the value is TRUE.

To test the function, this next example passes the root node of the book.xml document to the recursive getNodesInfo function, which then prints the tags and values of the entire DOM tree:

<?php //Create a document instance $doc = new DOMDocument(); //Load the Book.xml file $doc->load( 'Book.xml' ); //Setting the objects tree root $root = $dom->firstChild; // Recursive function to list all nodes of a subtree function getNodesInfo($node) { if ($node->hasChildNodes()) { $subNodes = $node->childNodes; foreach ($subNodes as $subNode) { if (($subNode->nodeType != 3) || (($subNode->nodeType == 3) &&(strlen(trim($subNode->wholeText))>=1))) { echo "Node name: ".$subNode->nodeName."\n"; echo "Node value: ".$subNode->nodeValue."\n"; } getNodesInfo($subNode); } } } //The getNodesInfo function call getNodesInfo($root); ?>

Figure 1 shows a small part of the output:

Figure 1. Document Contents: The figure shows a portion of the output from running the book.xml file through the getNodesInfo recursive method.

Adding New Nodes

The DOMNode interface includes several methods for creating nodes and inserting them into a DOM tree. To create new nodes, use either the createElement or createTextNode method. Then, to add the new nodes to a DOM tree, call either the appendChild or insertBefore method. The appendChild method adds a new child node to the end of the specified node's list of child nodes, while the insertBefore method will insert a new child before a specified node.

Here are the prototypes for the methods:

  • DOMElement createElement(string $name [, string $value ]): This method creates an instance of the DOMElement class. The $name argument represents the tag name for the new element, and the $value argument represents the value of the element. You can also set the value later, using the DOMElement->nodeValue property.
  • DOMText createTextNode(string $content): This method creates an instance of the DOMText class. The $content argument represents the text content for the new text node.
  • DOMNode DOMNode::appendChild(DOMNode $newnode): This function appends the $newnode argument at the end of an existing list of child nodes, or creates a new child node list containing the specified node.
  • DOMNode DOMNode::insertBefore(DOMNode $newnode [,DOMNode $refnode]): This method inserts the $newnode argument before the reference node specified by $refnode. If $refnode is missing, the new node is prepended to the node's list of child nodes.

The following example creates a <bibliography> node and appends it to the end of the tree:

//Create a new element $newElement = $dom->createElement('bibliography','Martin Didier, Professional XML'); // Add it to the root using the appendChild method //The appendChild function call appendNewChild($root,$newElement); //This function appends a new child node function appendNewChild($currentNode, $node) { $currentNode->appendChild($node); }

Figure 2. The Appended Node: The figure shows the new <bibliography> node and its contents at the end of the document.

If you run the results through the getNodeInfo() method, you'll see output similar to Figure 2.

This next example adds a new <foreword> child before the <publisher> node.

//create a new <foreword> element $newElement = $dom->createElement('foreword', 'What I love about this book is that it '. 'grew out of just such a process, '. 'and shows it on every page.'); //Set the reference node $allContents = $dom->getElementsByTagName('publisher'); $contents = $allContents->item(0); //Call the insertNewChild function insertNewChild($contents,$newElement); //This function inserts a new child //as the first child of $currentNode function insertNewChild($currentNode, $node) { $currentNode->insertBefore( $node, $currentNode->firstChild); }

Running the modified document through getNodesInfo shows the new node (see Figure 3).

Figure 3. Inserting Nodes: This output shows the new <foreward> child node inserted before the <publisher> node.

Thanks for your registration, follow us on our social networks to keep up-to-date