I have an 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>
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?
$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);
XPath Terminology. Nodes. In XPath, there are seven kinds of nodes: element, attribute, text, namespace, processing-instruction, comment, and document nodes. XML documents are treated as trees of nodes. The topmost element of the tree is called the root element. Look at the following XML document:
The removeChild () method removes a specified node. When a node is removed, all its child nodes are also removed. This code will remove the first <book> element from the loaded xml:
The XPathNavigatorclass provides the DeleteSelfmethod to delete the current node an XPathNavigatorobject is currently positioned on from an XML document. After a node has been deleted using the DeleteSelfmethod, it is no longer reachable from the root of the XmlDocumentobject.
Remove the element node by using the removeChild () method from the parent node Remove Myself - Remove the Current Node The removeChild () method is the only way to remove a specified node. When you have navigated to the node you want to remove, it is possible to remove that node using the parentNode property and the removeChild () method:
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::*
.
The found node is not a child of the document so, you need to remove it from its own parent: $node->parentNode->removeChild($node);
.
I suggest using a foreach
to avoid problems if the node doesn't exists.
$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>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With