2014-01-08 150 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); 
}