I need to append childnodes to their parent nodes, but parent node should be div
.
I need to check, if parent node is not div
then, check parent's parent node until I get div node. How to do it?
XML file
<div class="parent">
<div class="boxed-text">box text1</div>
<li>
<div class="boxed-text">box text2</div>
<p>para</p>
</li>
<div class="boxed-text">box text3</div>
<p>para</p>
</div>
Expected output(should append to the div parent node)
<div class="parent">
<li>
<p>para</p>
</li>
<p>para</p>
<div class="boxed-text">box text1</div>
<div class="boxed-text">box text2</div>
<div class="boxed-text">box text3</div>
</div>
But I have got an output like below:(i.e. parent node of boxed-text 2 is li
tag so, it get appended there instead of div parent node. How to get only div parent node to append child nodes? )
<div class="parent">
<li>
<p>para</p>
<div class="boxed-text">box text2</div>
</li>
<p>para</p>
<div class="boxed-text">box text1</div>
<div class="boxed-text">box text3</div>
</div>
my code:
$dom = new DOMDocument;
$dom->load("new_test.xml", LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD);
$xp = new DOMXPath($dom);
$xp->registerNamespace("php", "http://php.net/xpath");
$div = $xp->query("//div[@class='boxed-text']");
foreach($div as $divv) {
$divv->parentNode->appendChild($divv);
}
$r = $dom->saveXML();
You append the node to their parent node, but this will just move them to the last position inside the parent - it will not change the parent.
Xpath has a concept of axes. The default axis is child
- the children of the current context. But here a several others including ancestor
which represents the path back to the document root.
$dom = new DOMDocument;
$dom->preserveWhiteSpace = false;
$dom->formatOutput = true;
$dom->load("new_test.xml", LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD);
$xp = new DOMXPath($dom);
$xp->registerNamespace("php", "http://php.net/xpath");
$divs = $xp->evaluate("//div[@class='boxed-text']");
foreach($divs as $div) {
$ancestor = $xp->evaluate('ancestor::div[1]', $div)->item(0);
if ($ancestor) {
$ancestor->appendChild($div);
}
}
echo $dom->saveXML();
Output:
<?xml version="1.0"?>
<div class="parent">
<li>
<p>para</p>
</li>
<p>para</p>
<div class="boxed-text">box text1</div>
<div class="boxed-text">box text2</div>
<div class="boxed-text">box text3</div>
</div>
Another way would be to traverse the parent div elements and get the boxed-text descendants for each of them:
$parents = $xp->evaluate("//div[.//div[@class='boxed-text']]");
foreach ($parents as $parent) {
foreach ($xp->evaluate(".//div[@class='boxed-text']", $parent) as $text) {
$parent->appendChild($text);
}
}
Collected from the Internet
Please contact [email protected] to delete if infringement.
Comments