Loop Over Domdocument

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);
}
}
}

Iterating over elements from DOMDocument::getElementsByTagName() doesn't work

The problem seems to be that you are changing the document structure while trying to iterate over it.

The alternative is to use XPath, which will take it's own copy of the nodes for you to loop over, the changes are fairly small, but will give the output your after...

public function replace() {
$xp = new DOMXPath($this->document);

foreach ($this->tags as $name => $callable) {
$elements = $xp->query("//".$name);
foreach ($elements as $element) {
$callable($element, $this->document);
}
}

return $this->document->saveHTML();
}

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

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 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"

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";
}

}
}

Loop through elements and parse them whith DOMDocument() in PHP

Setting multiple values in the loop like this $data['data_categorie'] = using the same key for the array $data = array(); will overwrite the values on every iteration.

As you have multiple items, you could create a temporary array $temp = []; to store the values and add the array to the $data array after storing all the values for the current iteration.

As you are already using DOMXpath, you could get the div with class="list" using an expression like //div[@class="list"]/div and loop the childNodes checking for nodeName input and get that value plus the value of the next sibling which is the value of the label

$data = array();
$xp = new DOMXpath($dom);
$items = $xp->query('//div[@class="list"]/div');
foreach($items as $item) {
$temp["data_categorie"] = $item->getAttribute("data-categories");
foreach ($item->childNodes as $child) {
if ($child->nodeName === "input") {
$temp["input_value"] = $child->getAttribute("value");
$temp["label_text"] = $child->nextSibling->nodeValue;
}
}
$data[] = $temp;
}

print_r($data);

Output

Array
(
[0] => Array
(
[data_categorie] => 57 48
[input_value] => 119
[label_text] => Aquariums

)

[1] => Array
(
[data_categorie] => 47
[input_value] => 120
[label_text] => Arènes et stades

)

)

Php demo

How do I loop through HTML DOM nodes?

I am guessing OP was not specific for DIV elements, here's a more dynamic approach:

So first you wanna get the first container, in your case it's:

var mainEl = document.getElementById('main');

Once you have that, each DOM element has a .children property with all child nodes. Since DOM is a tree object, you can also add a flag to achieve recursive behavior.

function visitChildren(el, visitor, recursive) {
for(var i = 0; i < el.children.length; i++) {
visitor(children[i]);
if(recursive)
visitChildren(children[i], visitor, recursive);
}
}

And now, let's say you want to change all div backgrounds to red:

visitChildren(mainEl, function(el) { el.style.background = 'red' });


Related Topics



Leave a reply



Submit