开发者

Filtering within DOM XPath query results

So I'm using XPath to search a rather large XML document. What I'd like to do is after getting the initial results, search again within those results (and then search up to 2 more times). However, I'm not sure how to go about searching again. I tried this:

Multiple queries using '|' operator:

    $dom = new DOMDocument();
    $dom->load('courses.kml');
    $xpath = new DOMXPath($dom);
    $xpath->registerNamespace('kml', "http://earth.google.com/kml/2.1");
    //merge queries using | operator 
$query = $xpath->query("//kml:Placemark[kml:type='".$_POST['type']."'] | //kml:Placemark[kml:club_type='".$_POST['club_type']."']"); 

            foreach($query as $result){
                 echo $result->nodeValue . "<br /><br />";
            }

Apply a 2nd XPath expression to first query object:

$dom = new DOMDocument();
$dom->load('courses.kml');
$xpath = new DOMXPath($dom);
$xpath->registerNamespace('kml', "http://earth.google.com/kml/2.1");
$query = $xpath->query("//kml:Placemark[kml:type='".$_POST['type']."']");

$xpath2 = new DOMXPath($query);
$query2 = $xpath2->query("//[club_type='".$_POST['club_type']."']");

        //echo $result->nodeValue . "<br /><br />";
        foreach($query2 as $result2){
             echo $result2->nodeValue . "<br /><br />";
        }

But that doesn't seem to work, so I tried:

Run two separate instances and merge

//1st
$dom = new DOMDocument();
$dom->load('courses.kml');
$xpath = new DOMXPath($dom);
$xpath->registerNamespace('kml', "http://earth.google.com/kml/2.1");
$query = $xpath->query("//kml:Placemark[kml:club_type='".$_POST['club_type']."']");

//2nd
$dom2 = new DOMDocument();
$dom2->load('courses.kml');
$xpath2 = new DOMXPath($dom2);
$xpath2->registerNamespace('kml', "http://earth.google.com/kml/2.1");
$query2 = $xpath2->query("//kml:Placemark[kml:type='".$_POST['type']."']");

//merge object
$obj_merged = (array) array_merge((array) $query, (array) $query2);
foreach($obj_merged as $result){
    echo $result->nodeValue . "<br /><br />";
}

And I've tried various other things including following the suggestions at: php xpath: query within a query result, though it's not exactly the same thing, I still couldn't produce results. I'm not getting any errors, just blank pages.

To clarify:

If this were my XML document:

<?xml version="1.0" encoding="UTF-8"?>
<kml xmlns="http://earth.google.com/kml/2.1">
    <Document>
      <Placemark id="plac开发者_StackOverflow社区emark1">
          <name>Test Country Club1 </name>
          <description>
              <![CDATA[
                 <div class="contact">Post Office Box 329 <a href="#" target="_blank">website</a></div>
              ]]>
          </description>
          <alpha>a</alpha>
          <position>2</position>
          <type>Public/Daily Fee</type>
          <club_type>other</club_type>
          <hole_type>9hole</hole_type>
          <styleUrl>#nineholeStyle</styleUrl>
          <Point>
              <coordinates>-79.285576,37.111809</coordinates>
          </Point>
      </Placemark>
      <Placemark id="placemark2">
          <name>Test Country Club2</name>
          <description>
              <![CDATA[
                 <div class="contact">Post Office Box 329 <a href="#" target="_blank">website</a></div>
              ]]>
          </description>
          <alpha>a</alpha>
          <position>2</position>
          <type>Public/Daily Fee</type>
          <club_type>other</club_type>
          <hole_type>9hole</hole_type>
          <styleUrl>#nineholeStyle</styleUrl>
          <Point>
              <coordinates>-79.285576,37.111809</coordinates>
          </Point>
      </Placemark>
      <Placemark id="placemark3">
          <name>Test Country Club3</name>
          <description>
              <![CDATA[
                 <div class="contact">Post Office Box 329 <a href="#" target="_blank">website</a></div>
              ]]>
          </description>
          <alpha>a</alpha>
          <position>3</position>
          <type>Public/Daily Fee</type>
          <club_type>other</club_type>
          <hole_type>9hole</hole_type>
          <styleUrl>#nineholeStyle</styleUrl>
          <Point>
              <coordinates>-79.285576,37.111809</coordinates>
          </Point>
      </Placemark>
      <Placemark id="placemark4">
          <name>Test Country Club4</name>
          <description>
              <![CDATA[
                 <div class="contact">Post Office Box 329 <a href="#" target="_blank">website</a></div>
              ]]>
          </description>
          <alpha>a</alpha>
          <position>4</position>
          <type>Private</type>
          <club_type>Greengrass</club_type>
          <hole_type>18hole</hole_type>
          <styleUrl>#nineholeStyle</styleUrl>
          <Point>
              <coordinates>-79.285576,37.111809</coordinates>
          </Point>
      </Placemark>
  </Document>
</kml>

How would i search for type, club_type, hole_type, and/or alpha. Say if i wanted to only return Private Greengrass 18hole clubs that start with 'a'


only return Private Greengrass 18hole clubs that start with 'a'

In XPath that would look like (I'm assuming by "start with 'a'" that you mean the <alpha> is that letter)

/kml:kml/kml:Document/kml:Placemark[
        kml:type      = 'Private'
    and kml:club_type = 'Greengrass'
    and kml:hole_type = '18hole'
    and kml:alpha     = 'a'
]

Also remember that you can look at the length property of the DOMNodeList returned from DOMXPath::query(). For example

$query = "
    /kml:kml/kml:Document/kml:Placemark[
            kml:type      = 'Private'
        and kml:club_type = 'Greengrass'
        and kml:hole_type = '18hole'
        and kml:alpha     = 'a'
    ]
";
$places = $xpath->query($query);

echo "Found {$places->length} matching places" . PHP_EOL;
foreach ($places as $place) {
    $name = $place->getElementsByTagName('name')->item(0)->textContent;
    echo " - " . $name . PHP_EOL;
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜