DOMNode :: getElementsByTagName()返回一個「活動」列表。如果文檔發生更改,它會發生變化。您替換節點,這樣列表也會改變。
這裏有三種方法可以解決這個問題。
角色節點列表到一個數組:
$Autos = iterator_to_array($dom->getElementsByTagName('cars'));
循環列表中從最後一個節點到第一:
for ($i = $Autos->length - 1; $i >= 0; $i--) {
使用XPath取節點:
個$xpath = new DOMXPath($dom);
$Autos = $xpath->evaluate('//cars');
XPath表達式很多更加靈活和強大然後將DOM方法來獲取節點和結果不是「活」。例如,您可以執行如下操作:
$Autos = $xpath->evaluate('//cars[@manufacturer = "SomeCompanyName"]');
這是您源中的另一個問題。您只用一個創建的節點替換該節點。因此,它取代了第一個節點,然後同一個節點替換了第二個節點,直到它取代了列表中的最後一個節點。
您將需要克隆創建的節點:
$Autos->item($i)->parentNode->replaceChild(
$NewElement->cloneNode(TRUE), $Autos->item($i)
);
節點列表實現Traversable接口的。你可以使用foreach()。
foreach ($xpath->evaluate('//cars') as $i => $car) {
$car->parentNode->replaceChild($NewElement->cloneNode(TRUE), $car);
echo " i= " .$i;
}
作爲一個側面說明。構建新的目標XML文檔並將節點複製到它然後操縱現有文檔通常會更容易。 XSLT是專門用於此任務的特定語言。
來源
2015-01-15 17:02:07
ThW