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
How to Deploy Correctly When Using Composer's Develop/Production Switch
How to Use PHP to Get the Current Year
How Does This Giant Regex Work
How to Increase My "Advanced" Knowledge of PHP Further? (Quickly)
How to Detect Fake Users ( Crawlers ) and Curl
How to Hash Long Passwords (>72 Characters) with Blowfish
How to Enable Curl for an Installed Ubuntu Lamp Stack
Phpmailer Character Encoding Issues
Laravel 5.3 New Auth::Routes()
Authenticate User for Socket.Io/Nodejs
How to Get Wordpress Post Featured Image Url
Remove First 4 Characters of a String with PHP
Handle Guzzle Exception and Get Http Body
Any Way to Break If Statement in PHP