XML Dom 用于在 replacechild 之后停止循环
XML Dom for next stop looping after replacechild
然后我尝试在第一个替换循环停止后使用此代码
$Autos->length = 10
$Autos = $dom->getElementsByTagName('cars'); // Find Sections
$NewElement = $dom->createElement('hello','hi');
for ($i = 0; $i < $Autos->length; $i++)
{
$Autos->item($i)->parentNode->replaceChild($NewElement, $Autos->item($i));
echo $Autos->length . " i= " .$i;
}
所以 $i 总是 = 0
为什么会这样?
DOMNode::getElementsByTagName() returns 一个 "live" 列表。如果更改文档,它会更改。您替换了节点,因此列表也发生了变化。
这里有三种方法可以解决这个问题。
将节点列表转换为数组:
$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 获取节点的方法灵活和强大得多,结果不是 'live'。例如,您可以执行以下操作:
$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 是专门用于此任务的特定语言。
然后我尝试在第一个替换循环停止后使用此代码
$Autos->length = 10
$Autos = $dom->getElementsByTagName('cars'); // Find Sections
$NewElement = $dom->createElement('hello','hi');
for ($i = 0; $i < $Autos->length; $i++)
{
$Autos->item($i)->parentNode->replaceChild($NewElement, $Autos->item($i));
echo $Autos->length . " i= " .$i;
}
所以 $i 总是 = 0 为什么会这样?
DOMNode::getElementsByTagName() returns 一个 "live" 列表。如果更改文档,它会更改。您替换了节点,因此列表也发生了变化。
这里有三种方法可以解决这个问题。
将节点列表转换为数组:
$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 获取节点的方法灵活和强大得多,结果不是 'live'。例如,您可以执行以下操作:
$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 是专门用于此任务的特定语言。