dongrenzheng1619
2011-03-18 18:45
浏览 82
已采纳

在DOM XPath查询结果中过滤

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="placemark1">
          <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'

  • 写回答
  • 关注问题
  • 收藏
  • 邀请回答

1条回答 默认 最新

  • dqwh1218 2011-03-18 20:45
    已采纳

    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;
    }
    
    已采纳该答案
    打赏 评论

相关推荐 更多相似问题