[英]Removing nodes in XML with XPath and PHP
I have an XML
: 我有一个
XML
:
<root>
<level name="main">
<level name="sub_1">
<content id="abc123" />
</level>
</level>
</root>
I would like to search for the node with id
that is abc123
and delete the <content>
and its parent <level>
我想搜索
id
为abc123
的节点并删除<content>
及其父<level>
So the end result would be: 所以最终的结果是:
<root>
<level name="main">
</level>
</root>
I have tried this in PHP without result, what am I doing wrong? 我在PHP中试过没有结果,我做错了什么?
$doc = new DOMDocument;
$doc->loadxml($xml_from_file);
$xpath = new DOMXPath($doc);
$node_list = $xpath->query("content[@id='abc123']/parent::*");
$node = $node_list->item(0);
$doc->removeChild($node);
Here are two issues with your source. 以下是您的来源的两个问题。
The expression does only match child nodes. 表达式仅匹配子节点。 You need to start it with
//
to match any node: //content[@id='abc123']/parent::*
. 你需要用
//
来匹配任何node: //content[@id='abc123']/parent::*
。
The found node is not a child of the document so, you need to remove it from its own parent: $node->parentNode->removeChild($node);
找到的节点不是文档的子节点,因此需要将其从自己的父
$node->parentNode->removeChild($node);
删除: $node->parentNode->removeChild($node);
. 。
I suggest using a foreach
to avoid problems if the node doesn't exists. 如果节点不存在,我建议使用
foreach
来避免问题。
$document = new DOMDocument;
$document->loadxml($xmlString);
$xpath = new DOMXPath($document);
foreach ($xpath->evaluate("//content[@id='abc123']/parent::*") as $node) {
$node->parentNode->removeChild($node);
}
echo $document->saveXml();
<?php
$xml_from_file = '<root>
<level name="main">
<level name="sub_1">
<content id="abc123" />
</level>
</level>
</root>';
$doc = new DOMDocument;
$doc->loadxml($xml_from_file);
$xpath_selector = new DOMXPath($doc);
//Here you forget at the begin the //
$node_list = $xpath_selector->query("//content[@id='abc123']/parent::*");
//here you get the reference to the parent of content
$node = $node_list->item(0);
//but for remove the child you need to go to the parent node
$node->parentNode->removeChild($node);
echo $doc->saveXML();
?>
Output: 输出:
<root>
<level name="main">
</level>
</root>
This is kind of a hack but I got it to work with your example. 这是一种黑客攻击,但我让它与你的例子一起工作。 One problem is likely with your
xpath
query--note the //
at the beginning. 您的
xpath
查询可能存在一个问题 - 请注意//
开头的//
。
$xml_string = '<root>
<level name="main">
<level name="sub_1">
<content id="abc123" />
</level>
</level>
</root>';
// using SimpleXMLElement instead of DOMDocument
$xml = new SimpleXMLElement($xml_string);
// standardize the string version of the xml so str_replace works
$xml_string = $xml->asXML();
// search for the target; note the // at the beginning of the query
$target = $xml->xpath("//content[@id='abc123']/parent::*");
// use simple string replacement to remove the node
echo str_replace($target[0]->asXML(), '', $xml_string);
Not very elegant, but it seemed to take care of your problem. 不是很优雅,但它似乎照顾你的问题。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.