我正在尝试使用DOM Document删除php中的多个元素,但它不起作用,因为我希望它能够工作。
<iPhone>
<enAttentePush>
<UDID>dd6fc8032f0bf4c4b3a9c60f523900c9ad463b620a83b6473eda9a12b2c9d47f</UDID>
<Message>someDataHere</Message>
</enAttentePush>
<enAttentePush>
<UDID>dd6fc8032f0bf4c4b3a9c60f523900c9ad463b620a83b6473eda9a12b2c9d47f</UDID>
<Message>someDataHere</Message>
</enAttentePush>
</iPhone>
我想循环到我的xml文档中,然后擦除所有元素以获取空文件。
以下是我在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);
}
它只删除一个节点,一般是最后一个节点。
我怎样才能循环思考我的节点并在每次看到节点时删除它?
非常感谢。
答案 0 :(得分:3)
getElementsByTagName()
返回“live”迭代器,当您从列表中删除元素时,列表会更改。您可以将迭代器转换为数组以获取列表的副本。
$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();
输出:
<?xml version="1.0"?>
<iPhone>
</iPhone>
更简单的方法是将原始文档中的文档元素复制到新文档中 之一:
$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();
输出:
<?xml version="1.0"?>
<iPhone/>
要删除特定节点,请使用Xpath选择它们。这允许复杂的条件。
$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();
答案 1 :(得分:2)
最近我必须在自己的网站上执行此操作,并发现如果将数组中的元素排队,则可以在此之后轻松删除它们。这是一个使用的小片段,希望它可以帮助你:
$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 :(得分:1)
正如评论中已经提到的,使用while
而不是foreach
来迭代DOMNodeList:
$i = $domNodeList->length;
while ($i > 0) {
$i--;
$domElement = $domNodeList->item($i);
$domElement->parentNode->removeChild($domElement);
}