How to Iterate Through Dom Elements in PHP

How do I iterate through DOM elements in PHP?

Not tested, but what about:

$elements = $dom->getElementsByTagName('foo');
$data = array();
foreach($elements as $node){
foreach($node->childNodes as $child) {
$data[] = array($child->nodeName => $child->nodeValue);
}
}

Iterate through different DOM nodes and elements with php

A for loop might be more appropriate:

$times = $data->getElementsByTagName('time');
$emails = $data->getElementsByTagName('mail');

for ($i=0; $i < $times->length; $i++) {
$ts = (string) $times->item(0)->nodeValue;
if ( $ts < time()-1 ) {
$times->item(0)->nodeValue = $ts;
$email = $emails->item(0)->nodeValue;
}
}

Demo.

Iterate through DOM document with PHP

Not only the elements are nodes. You output the name of the nodes without children. In your XML that are text nodes only.

You could check the node type ... or use XPath:

$xml = <<<'XML'
<?xml version='1.0' encoding='ISO-8859-1'?><user><name>Michael Taylor</name><offers>0</offers><address><street>Ringstreet 8</street><zip>1100</zip><city>Norther</city></address><credit>473.43</credit></user>
XML;

$dom = new DOMDocument();
$dom->loadXml($xml);
$xpath = new DOMXPath($dom);

foreach ($xpath->evaluate('//*[count(*) = 0]') as $node) {
var_dump($node->nodeName);
}

* matches elements nodes, //* means any element node in the document, [count(*) = 0] limits it to nodes without child element nodes.

Output:

string(4) "name"
string(6) "offers"
string(6) "street"
string(3) "zip"
string(4) "city"
string(6) "credit"

Loop over DOMDocument

Try this:

$doc = new DOMDocument();
$doc->loadHTML($html);
showDOMNode($doc);

function showDOMNode(DOMNode $domNode) {
foreach ($domNode->childNodes as $node)
{
print $node->nodeName.':'.$node->nodeValue;
if($node->hasChildNodes()) {
showDOMNode($node);
}
}
}

How to iterate through elements in DOMNodeList?

DOMNodeList implements Traversable, just use foreach()

foreach($nodeList as $node) {
//...
}

Of course a for is possible, too.

$length = $nodeList->length;
for ($i = 0; $i < $length; $i++) {
$node = $nodeList->item($i);
//...
}

To get all the text content inside a node, the $nodeValue or $textContent properties can be used:

$text = '';
foreach($nodeList as $node) {
$text .= $node->textContent;
}

But this is for a node list. You said that this is the text content of a paragraph. If you have the paragraph as an DOMElement object, it has $nodeValue and $textContent properties as well.

$text = $paragraphNode->textContent;

And if you fetched the nodes via Xpath, DOMXpath::evaluate() can return the text content as a string.

$xpath = new DOMXpath($dom);
$text = $xpath->evaluate('string(//p[1])');

Looping Through Multiple HTML Elements with DOMDocument

<?php
$html = '
<div class="container">

<div class="info">
<h3>Info 1</h3>
<span class="title">Title for Info 1</span>
<a href="http://www.example.com/1">Link to Example 1</a>
</div> <!-- /info -->

<div class="info">
<h3>Info 2</h3>
<span class="title">Title for Info 2</span>
<a href="http://www.example.com/2">Link to Example 2</a>
</div> <!-- /info -->

<div class="info">
<h3>Info 3</h3>
<span class="title">Title for Info 3</span>
<a href="http://www.example.com/3">Link to Example 3</a>
</div> <!-- /info -->

</div> <!-- /container -->
';

$dom_document = new DOMDocument();

$dom_document->loadHTML($html);
$dom_document->preserveWhiteSpace = false;

//use DOMXpath to navigate the html with the DOM
$dom_xpath = new DOMXpath($dom_document);

$elements = $dom_xpath->query("//*[@class='info']");

if (!is_null($elements)) {

foreach ($elements as $element) {
echo "\n[". $element->nodeName. "]";

$nodes = $element->childNodes;
foreach ($nodes as $node) {
echo $node->nodeValue. "\n";
}

}
}

looping through all children of element with domdocument and extract text-content

One of the most easy ways to do that with DOMDocument is with the help of DOMXPath.

Taking your question literally:

How can I loop through all children of office:text?

This can be represented as an XPath expression:

//office:text/child::node()

However you're using a little wrong wording here. It's not only all children, but also the children of the children and so on and so forth - that is all descendants:

//office:text/descendant::node()

Or with the abbreviated syntax:

//office:text//node()

Compare with: XPath to Get All ChildNodes and not the Parent Node

For that to loop over in PHP, you need to register the namespace for the office prefix and then you loop over the xpath result with a foreach:
$xpath = new DOMXPath($reader);
$xpath->registerNamespace('office', $xml_namespace_uri_of_office_namespace);

$descendants = $xpath->query('//office:text//node()');
foreach ($descendants as $node) {
// $node is a DOMNode as of DOMElement, DOMText, ...
}

XPath not in general but in PHP's libxml based libraries does return the nodes in document-order. That is the order you're looking for.

Compare with: XPath query result order

Ho to loop through Dom with PHP and find data-id

I'd go with first looking for all child nodes within body which have data-id attribute using xpath queries then appending to them or building an array:

$dom = new DOMDocument();
$dom->loadHTML($html, LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD);
$dox = new DOMXPath($dom);
$nodes = $dox->query('/html/body//*[@data-id]');
$array = [];
foreach ($nodes as $key => $node) {
$node->appendChild(new DOMText('add text'));
$array[$key] = ['data-id' => 'add text'];
}
echo $dom->saveHTML();


Related Topics



Leave a reply



Submit