php SimpleXML - 删除 xpath 节点

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2442314/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-25 06:29:46  来源:igfitidea点击:

SimpleXML - Remove xpath node

phpsimplexml

提问by Peter John

I'm a little confused as to how I can delete a parent node of something which I can find via an xpath search:

我对如何删除我可以通过 xpath 搜索找到的东西的父节点有点困惑:

$xml = simplexml_load_file($filename);
$data = $xml->xpath('//items/info[item_id="' . $item_id . '"]');
$parent = $data[0]->xpath("parent::*");
unset($parent);

So, it finds the item id, no problems there - but the unset isn't getting rid of this <items>node. All I want to do is remove the <items>...</items>for this product. Obviously, there are loads of <items>nodes in the xml file so it can't do unset($xml->data->items)as that would delete everything.

所以,它找到了项目 id,那里没有问题 - 但 unset 并没有摆脱这个<items>节点。我想要做的就是删除<items>...</items>此产品的 。显然,<items>xml 文件中有大量节点,所以它不能这样做,unset($xml->data->items)因为这会删除所有内容。

Any ideas much appreciated :-)

任何想法都非常感谢:-)

回答by VolkerK

<?php
$xml = new SimpleXMLElement('<a><b/></a>');
unset($xml->b);
echo $xml->asxml();

this works as intended (removing the <b/> element fromt he document) because the __unset() method(or the equivalent in the modules code) is called.
But when you call unset($parent);it only removes the object reference stored in $parent, but it doesn't affect the object itself or the document stored in $xml. I'd revert to DOMDocumentfor this.

这按预期工作(从文档中删除 <b/> 元素),因为__unset() 方法(或模块代码中的等效方法)被调用。
但是当你调用unset($parent);它时,它只会移除存储在 $parent 中的对象引用,而不会影响对象本身或存储在 $xml 中的文档。为此,我将恢复到DOMDocument

<?php
$doc = new DOMDOcument;
$doc->loadxml('<foo>
  <items>
    <info>
      <item_id>123</item_id>
    </info>
  </items>
  <items>
    <info>
      <item_id>456</item_id>
    </info>
  </items>
  <items>
    <info>
      <item_id>789</item_id>
    </info>
  </items>
</foo>');
$item_id = 456;

$xpath = new DOMXpath($doc);
foreach($xpath->query('//items[info/item_id="' . $item_id . '"]') as $node) {
  $node->parentNode->removeChild($node);
}
echo $doc->savexml();

prints

印刷

<?xml version="1.0"?>
<foo>
  <items>
    <info>
      <item_id>123</item_id>
    </info>
  </items>

  <items>
    <info>
      <item_id>789</item_id>
    </info>
  </items>
</foo>

回答by Max

It works like this for me. Not unset($parent);but unset($parent[0]);:

它对我来说是这样的。不unset($parent);但是unset($parent[0]);

$res    = $xml->xpath('//key/k[. = "string"]/parent::*');
$parent = $res[0];
unset($parent[0]);

This works by creating a self-reference to the simplexml-elementin $parent(or $res[0]).

这是通过在(或) 中创建对 simplexml 元素自引用来实现的$parent$res[0]

For a more detailed explanation please see a related answerin the related question Remove a child with a specific attribute, in SimpleXML for PHP.

有关更详细的解释,请参阅相关问题Remove a child with a specific attribute, in SimpleXML for PHP 中的相关答案

回答by cemil

One way is to import the SimpleXML node into DOMDocument and then remove within DOMDocument. Not really straight forward, but it works:

一种方法是将 SimpleXML 节点导入 DOMDocument,然后在 DOMDocument 中删除。不是很直接,但它有效:

$xml = simplexml_load_file($filename);

$result = $xml->xpath("/cardsets/cardgroup");

foreach ($result as $el)
{
    if ($el['id'] == $id)
    {
        $domRef = dom_import_simplexml($el);
        $domRef->parentNode->removeChild($domRef);
        $dom = new DOMDocument('1.0');
        $dom->preserveWhiteSpace = false;
        $dom->formatOutput = true;
        $dom->loadXML($xml->asXML());
        $dom->save($filename);
        break;
    }
}

回答by pestaa

I'd surely approach this problem as a filtering one - not a removing one.

我肯定会将此问题视为过滤问题 - 而不是删除问题。

Thus, copying needed nodes into another string or build up another XML document for that matter. You know what tools you use for such scenarios.

因此,将需要的节点复制到另一个字符串中或为此构建另一个 XML 文档。您知道在此类场景中使用了哪些工具。

I think this not only solves your problem, but probably keeps your easier to read and understand. Not sure about performance hits, though. Tell us how many nodes you regularly work with.

我认为这不仅解决了您的问题,而且可能使您更易于阅读和理解。不过,不确定性能是否受到影响。告诉我们您经常使用多少个节点。