我想删除标题与$titleArray
匹配的条目。
我的XML文件如下:
<products>
<product>
<title>Battlefield 1</title>
<url>https://www.google.de/</url>
<price>0.80</price>
</product>
<product>
<title>Battlefield 2</title>
<url>https://www.google.de/</url>
<price>180</price>
</product>
</products>
这是我的代码,但我认为它不起作用,我的IDE在这里说$node->removeChild($product);
- &gt; “期望的DOMNode,得到了DOMNodeList”
有什么问题,我该如何解决?
function removeProduct($dom, $productTag, $pathXML, $titleArray){
$doc = simplexml_import_dom($dom);
$items = $doc->xpath($pathXML);
foreach ($items as $item) {
$node = dom_import_simplexml($item);
foreach ($titleArray as $title) {
if (mb_stripos($node->textContent, $title) !== false) {
$product = $node->parentNode->getElementsByTagName($productTag);
$node->removeChild($product);
}
}
}
}
谢谢你和问候!
答案 0 :(得分:0)
获取节点的大多数DOM方法都返回节点列表。您可以拥有多个具有相同名称的元素节点。因此结果将是一个列表(如果找不到任何内容,则为空列表)。您可以遍历列表并将逻辑应用于列表中的每个节点。
这个方法有两个问题。删除节点会修改文档。因此,您必须小心不要删除之后仍在使用的节点。它可能导致任何意想不到的结果。 DOMNode::getElementsByTagName()
返回一个节点列表,它是一个“实时”结果。如果删除列表实际更改的第一个节点,而不仅仅是XML文档。
DOMXpath::evaluate()
同时解决了两个问题。结果不是“实时”,因此您可以使用foreach()
迭代结果并删除节点。 Xpath表达式允许条件,因此您可以筛选和获取特定节点。不幸的是,Xpath 1.0现在有小写方法,但你可以回调PHP。
function isTitleInArray($title) {
$titles = [
'battlefield 2'
];
return in_array(mb_strtolower($title, 'UTF-8'), $titles);
}
$document = new DOMDocument();
$document->loadXml($xml);
$xpath = new DOMXpath($document);
$xpath->registerNamespace("php", "http://php.net/xpath");
$xpath->registerPHPFunctions('isTitleInArray');
$expression = '//product[php:function("isTitleInArray", normalize-space(title))]';
foreach ($xpath->evaluate($expression) as $product) {
$product->parentNode->removeChild($product);
}
echo $document->saveXml();
输出:
<?xml version="1.0"?>
<products>
<product>
<title>Battlefield 1</title>
<url>https://www.google.de/</url>
<price>0.80</price>
</product>
</products>