我的情况让我发疯。我想在我的feed中搜索具有特定值的元素(从数组派生),如果找到该值,则更改它的前一个兄弟元素的值。
我的Feed看起来像这样
<products>
<product>
<properties>
<property name="category">
<value>Fruits</value>
</property>
<property name="item">
<value>Banana</value>
</property>
</properties>
</product>
<product>
<properties>
<property name="category">
<value>Fruits</value>
</property>
<property name="item">
<value>Apple</value>
</property>
</properties>
</product>
<product>
<properties>
<property name="category">
<value>Fruits</value>
</property>
<property name="item">
<value>Carrot</value>
</property>
</properties>
</product>
</products>
如您所见,Feed中可能存在一些错误。对于这些实例,我创建了一个具有适当值的数组,如下所示:
$replacements = Array(
"Carrot" => "Vegetable"
);
现在,我想要选择具有property
键值的属性item
的每个$replacements
,然后选择属性为{{1}的上一个兄弟元素并使用匹配的category
值更改此值。
我想出了这个,但这只给了我一个没有输出的白色屏幕
$replacements
但我不明白为什么它不输出任何东西
答案 0 :(得分:2)
这里有一些事情:
array_key_exists($entry->nodeValue,$replacements)
nodeValue将包含property元素及其后代中的所有文本内容 - 包括换行符和空格。
... = $replacements[$entries->nodeValue];
你可能正在寻找$replacements[$entry->nodeValue]
但是你再次遇到与空白相同的问题。不仅如此,你还要用文本替换整个先前属性的nodeValue:
<property name="category">
<value>Fruits</value>
</property>
将成为:
<property name="category">Vegetable</property>
要解决这个问题,我建议您调整查询,以及如何解决要替换的目标值,以便摆脱->previousSibling->previousSibling
链接并更加明确。< / p>
foreach ($xpath->query('//property[@name="item"]/value') as $node) {
if (array_key_exists(trim($node->textContent), $replacements)) {
$target = $xpath->query(
'preceding-sibling::property/value/text()',
$node->parentNode
)->item(0);
$target->parentNode->replaceChild(
$dom->createTextNode($replacements[trim($node->textContent)]),
$target
);
}
}
echo $dom->saveXML();
...
<product>
<properties>
<property name="category">
<value>Vegetable</value>
</property>
<property name="item">
<value>Carrot</value>
</property>
</properties>
</product>
</products>
答案 1 :(得分:1)
您需要返回值,为了做到这一点,您需要更正您的查询
$query = '//property[@name = "item"]/value';
答案 2 :(得分:0)
您可以尝试使用完整路径,所以:
$query = '//products/product/properties/property[@name = "item"]/value';
$entries = $xpath->query($query);
foreach ($entries as $entry) {
if(array_key_exists($entry->nodeValue,$replacements)){
$entry->previousSibling->previousSibling->nodeValue = $replacements[$entries->nodeValue];
}
}
此外,您可以尝试使用context
(Manual):
$context = $document->getElementsByTagName('products')->item(0);
$query = './/property[@name = "item"]/value';//add a '.' before the query to make it relative to the context
$entries = $xpath->query($query, $context);
foreach ($entries as $entry) {
if(array_key_exists($entry->nodeValue,$replacements)){
$entry->previousSibling->previousSibling->nodeValue = $replacements[$entries->nodeValue];
}
}
在非常相似的情况下,这两种解决方案都适用于我。