问题
I'm trying to remove multiple elements in php using DOM Document, but it does not work as i wanted it to work.
<iPhone>
<enAttentePush>
<UDID>dd6fc8032f0bf4c4b3a9c60f523900c9ad463b620a83b6473eda9a12b2c9d47f</UDID>
<Message>someDataHere</Message>
</enAttentePush>
<enAttentePush>
<UDID>dd6fc8032f0bf4c4b3a9c60f523900c9ad463b620a83b6473eda9a12b2c9d47f</UDID>
<Message>someDataHere</Message>
</enAttentePush>
</iPhone>
I want to loop into my xml document and then erase all element to get an empty file.
Here is what i do in php :
$doc = new DOMDocument;
$doc->load('$myFile');
$domNodeList = $doc->getElementsByTagName('enAttentePush');
$arraySeen = array();
$arrayBug = array();
foreach ($domNodeList as $domElement)
{
//echo('loop / ');
$tempArray = array();
$aps = $domElement->getElementsByTagName('Message')->item(0)->nodeValue;
$udid = $domElement->getElementsByTagName('UDID')->item(0)->nodeValue;
if (!in_array($udid, $arraySeen))
{
$tempArray[]=$aps;
$tempArray[]=$udid;
$arrayBug[]=$tempArray;
$arraySeen[]=$udid;
}
echo("-- removed -- ");
$domElement->parentNode->removeChild($domElement);
}
It only delete only one node, the last one in general.
How can i do to loop thought my node and remove it each time i see a node ?
Thank you very much.
回答1:
I had to do this just recently on my own site and found that you if you queue up your elements in an array, you can remove them all quite easily after that. Here is a little snippet that use, hopefully it helps you out:
$doc = new DOMDocument;
$doc->load('$myFile');
$domNodeList = $doc->getElementsByTagName('enAttentePush');
$domArray = array(); //set up an array to catch all our nodes
foreach($domNodeList as $dom) {
$domArray[] = $dom;
}
// loop through the array and delete each node
foreach($domArray as $node){
$doc->documentElement->removeChild($node);
}
$doc->save('$myFile');
回答2:
getElementsByTagName() returns "live" iterator, the list changes the moment you remove the elements from the list. You can convert the iterator into an array to get a copy of the list.
$xml = <<<'XML'
<iPhone>
<enAttentePush>
<UDID>dd6fc8032f0bf4c4b3a9c60f523900c9ad463b620a83b6473eda9a12b2c9d47f</UDID>
<Message>someDataHere</Message>
</enAttentePush>
<enAttentePush>
<UDID>dd6fc8032f0bf4c4b3a9c60f523900c9ad463b620a83b6473eda9a12b2c9d47f</UDID>
<Message>someDataHere</Message>
</enAttentePush>
</iPhone>
XML;
$dom = new DOMDocument();
$dom->loadXml($xml);
$nodes = iterator_to_array($dom->getElementsByTagName('enAttentePush'));
foreach ($nodes as $node) {
$node->parentNode->removeChild($node);
}
echo $dom->saveXml();
Output:
<?xml version="1.0"?>
<iPhone>
</iPhone>
An easier way would be to copy the document element from the original document into a new one:
$xml = <<<'XML'
<iPhone>
<enAttentePush>
<UDID>dd6fc8032f0bf4c4b3a9c60f523900c9ad463b620a83b6473eda9a12b2c9d47f</UDID>
<Message>someDataHere</Message>
</enAttentePush>
<enAttentePush>
<UDID>dd6fc8032f0bf4c4b3a9c60f523900c9ad463b620a83b6473eda9a12b2c9d47f</UDID>
<Message>someDataHere</Message>
</enAttentePush>
</iPhone>
XML;
$source = new DOMDocument();
$source->loadXml($xml);
$target = new DOMDocument();
$target->appendChild(
$target->importNode($source->documentElement, FALSE)
);
echo $target->saveXml();
Output:
<?xml version="1.0"?>
<iPhone/>
To remove specific nodes, select them with Xpath. This allows for complex conditions.
$dom = new DOMDocument();
$dom->loadXml($xml);
$xpath = new DOMXpath($dom);
$nodes = $xpath->evaluate('/*/enAttentePush');
foreach ($nodes as $node) {
$node->parentNode->removeChild($node);
}
echo $dom->saveXml();
回答3:
As already mentioned in comment, use while instead of foreach to iterate the DOMNodeList:
$i = $domNodeList->length;
while ($i > 0) {
$i--;
$domElement = $domNodeList->item($i);
$domElement->parentNode->removeChild($domElement);
}
来源:https://stackoverflow.com/questions/21000907/php-remove-multiple-elements-with-dom