Search code examples
phpxmldomxpath

How to get the result of an xpath query in php?


I'm puzzled on how to extract the data from my xpath query. I'm using PHP 5.5.6 and I'm getting this result:

I'm all the countries:
DOMNodeList Object
(
    [length] => 0
)
1
I'm all the countries:
DOMNodeList Object
(
    [length] => 0
)
1
I'm all the countries:
DOMNodeList Object
(
    [length] => 0
)
1
I'm all the countries:
DOMNodeList Object
(
    [length] => 0
)
1

My XML file is (truncated to show only the first parts, I'm experimenting with large XML files):

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Data>
    <NewDataSet>
        <Table>
            <Country>Philippines</Country>
            <City>Subic Bay Weather Station</City>
        </Table>
        <Table>
            <Country>Philippines</Country>
            <City>Laoag</City>
        </Table>
        <Table>
            <Country>Philippines</Country>
            <City>Ninoy Aquino Inter-National Airport</City>
        </Table>
        <Table>
            <Country>Philippines</Country>
            <City>Davao Airport</City>
        </Table>
        <Table>
            <Country>Philippines</Country>
            <City>Clark Ab</City>
        </Table>
        <Table>
            <Country>Philippines</Country>
            <City>Legaspi</City>
        </Table>
        <Table>
            <Country>Philippines</Country>
            <City>Romblon</City>
        </Table>

And what I'm trying to do is to just show what's inside the Country tags via the xpath query. My code is:

<?php

    $reader = new XMLReader();
    $reader->open("countries.xml", "UTF-8");

    while($reader->read()){
        //echo var_dump($reader->nodeType), "<br/>";
        if($reader->nodeType == XMLReader::ELEMENT && $reader->localName == "Table"){
            $node = $reader->expand();
            $dom = new DOMDocument;
            $xp = new DomXPath($dom);
            $xp1 = $xp->query("//Country");
            echo "I'm all the countries: <pre>",print_r($xp1),"</pre>";

        }

    }

    $reader->close();


?>

I don't understand why I'm not getting a value for $xp1 that I can just use $xp1->nodeValue or $xp1->item(0)->nodeValue on. I've certainly tried, even though the returned object only had "length" to give back. I'm looking at the example Listing 5 on this site and it looks like I should be able to do this. What am I missing?


Solution

  • Your DOM is empty, you never add $node to it. Try:

    $reader = new XMLReader();
    $reader->open("countries.xml", "UTF-8");
    
    while($reader->read()){
        if($reader->nodeType == XMLReader::ELEMENT && $reader->localName == "Table"){
            $node = $reader->expand();
            $dom = new DOMDocument;
            $n = $dom->importNode($node, true);
            $dom->appendChild($n);
            $xp = new DomXPath($dom);
            $xp1 = $xp->query("//Country");
            echo "I'm all the countries: <pre>{$xp1->item(0)->nodeValue}</pre>";
    
        }
    
    }
    
    $reader->close();