I have one solution to the problem of the subject, but hack it and they are wondering if there is a better way to do this.
The following is an example of an XML file and a PHP CLI script that executes an xpath request specified as an argument. For this test case, on the command line:
./xpeg "//MainType[@ID=123]"
The strangest thing is this line, without which my approach does not work:
$result->loadXML($result->saveXML($result));
As far as I know, this just repeats the analysis of the modified XML, and it seems to me that this should not be necessary.
Is there a better way to execute xpath requests for this XML in PHP?
XML (note the default namespace binding):
<?xml version="1.0" encoding="utf-8"?> <MyRoot xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.example.com/data http://www.example.com/data/MyRoot.xsd" xmlns="http://www.example.com/data"> <MainType ID="192" comment="Bob site"> <Price>$0.20</Price> <TheUrl><![CDATA[http://www.example.com/path1/]]></TheUrl> <Validated>N</Validated> </MainType> <MainType ID="123" comment="Test site"> <Price>$99.95</Price> <TheUrl><![CDATA[http://www.example.com/path2]]></TheUrl> <Validated>N</Validated> </MainType> <MainType ID="922" comment="Health Insurance"> <Price>$600.00</Price> <TheUrl><![CDATA[http://www.example.com/eg/xyz.php]]></TheUrl> <Validated>N</Validated> </MainType> <MainType ID="389" comment="Used Cars"> <Price>$5000.00</Price> <TheUrl><![CDATA[http://www.example.com/tata.php]]></TheUrl> <Validated>N</Validated> </MainType> </MyRoot>
PHP CLI Script:
#!/usr/bin/php-cli <?php $xml = file_get_contents("xpeg.xml"); $domdoc = new DOMDocument(); $domdoc->loadXML($xml); // remove the default namespace binding $e = $domdoc->documentElement; $e->removeAttributeNS($e->getAttributeNode("xmlns")->nodeValue,""); // hack hack, cough cough, hack hack $domdoc->loadXML($domdoc->saveXML($domdoc)); $xpath = new DOMXpath($domdoc); $str = trim($argv[1]); $result = $xpath->query($str); if ($result !== FALSE) { dump_dom_levels($result); } else { echo "error\n"; } // The following function isn't really part of the // question. It simply provides a concise summary of // the result. function dump_dom_levels($node, $level = 0) { $class = get_class($node); if ($class == "DOMNodeList") { echo "Level $level ($class): $node->length items\n"; foreach ($node as $child_node) { dump_dom_levels($child_node, $level+1); } } else { $nChildren = 0; foreach ($node->childNodes as $child_node) { if ($child_node->hasChildNodes()) { $nChildren++; } } if ($nChildren) { echo "Level $level ($class): $nChildren children\n"; } foreach ($node->childNodes as $child_node) { if ($child_node->hasChildNodes()) { dump_dom_levels($child_node, $level+1); } } } } ?>
xml php xpath domxpath
danorton Jun 25 '11 at 2:23 2011-06-25 02:23
source share