Reputation: 2040
I have an XML file structured as:
<root>
<featured>
<title></title>
<tweet></tweet>
<img></img>
</featured>
</root>
The element is added dynamically , the user needs the option to remove the element on certain occasions,
I have tried a few variations of code including:
$featureddel = $xpath->query('//featured');
while ( $featureddel->hasChildNodes()){
$featureddel->removeChild($featureddel->childNodes->item(0));
}
which gives me a error:
PHP Fatal error: Call to undefined method DOMNodeList::hasChildNodes()
Ive also tried:
$featureddel= $dom->getElementsByTagName('featured');
$featureddel->parentNode->removeChild($featureddel);
which returns:
PHP Fatal error: Call to a member function removeChild() on a non-object
Upvotes: 2
Views: 13887
Reputation: 23216
Both DOMElement::getElementsByTagName
and DOMXPath::query
return a DOMNodeList
. Your code seems to be expecting a single DOMNode
instead. Try this:
$featureddel = $xpath->query('//featured');
// OR:
// $featuredde1 = $dom->getElementsByTagName('featured');
foreach ($featuredde1 as $node) {
$node->parentNode->removeChild($node);
}
Edit: This exact code works as expected for me (PHP 5.3, Debian Squeeze):
<?php
$xml = '<root>
<featured>
<title></title>
<tweet></tweet>
<img></img>
</featured>
</root>';
$dom = new DOMDocument();
$dom->loadXML($xml);
$featuredde1 = $dom->getElementsByTagName('featured');
foreach ($featuredde1 as $node) {
$node->parentNode->removeChild($node);
}
echo $dom->saveXML();
The output is:
<?xml version="1.0"?>
<root>
</root>
Upvotes: 5
Reputation: 2050
This should do it:
foreach ($featureddel as $node) {
$node->parentNode->removeChild($node);
}
You're probably just forgetting that with both xPath
and getElementsByTagName
you get a list (DOMNodeList
) of items. That object itself only has a property $length
, which you can use to determine how many objects are on the list, and function item($index)
, which returns specified DOMNode
from the list. DOMNodeList
is also iteratable through foreach
.
So besides foreach
like I wrote above you can also do:
for ($i = 0; $i < $featureddel->length; $i++) {
$temp = $featureddel->item($i); //avoid calling a function twice
$temp->parentNode->removeChild($temp);
}
But foreach
is usually more preferred.
Upvotes: 2