2014-01-08 112 views
1

我试图使用DOM文档在PHP中删除多个元素,但它不工作,因为我想让它工作。PHP使用DOM删除多个元素

<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

如果我依稀记得,删除一个节点搅得节点查询,这意味着你必须重新查询DOM直到所有节点都被删除。因此,而不是'的foreach(){}'你应该考虑使用'而(){}'。 – pp19dd

+0

好吧,我不知道如何使while循环使用DOM ... –

回答

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'); 
3

getElementsByTagName()返回“活”的迭代器,列表改变时刻,你从列表中删除的元素。您可以将迭代器转换为数组以获取列表的副本。

$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/> 

To r emove特定的节点,用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(); 
+0

非常感谢你THW我会用stckrboy液,是像我这样的小白更简单,但你回答我的帮助很大,我就看看@ xPath。非常感谢,非常感谢。 –

1

正如评论已经提到的,使用while而不是foreach以迭代的DOMNodeList:

$i = $domNodeList->length; 
while ($i > 0) { 
    $i--; 
    $domElement = $domNodeList->item($i); 
    $domElement->parentNode->removeChild($domElement); 
}