在DOM XPath查询结果中过滤

时间:2011-03-18 18:45:35

标签: php dom xpath

所以我使用XPath来搜索相当大的XML文档。我想做的是在获得初始结果后,在这些结果中再次搜索(然后再搜索2次)。但是,我不知道如何重新搜索。我试过这个:

使用“|”进行多次查询操作

    $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 />";
            }

将第二个XPath表达式应用于第一个查询对象:

$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 />";
        }

但这似乎不起作用,所以我尝试了:

运行两个单独的实例并合并

//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 />";
}

我尝试了其他各种各样的事情,包括遵循php xpath: query within a query result的建议,虽然它不完全相同,但我仍然无法产生结果。我没有收到任何错误,只是空白页。

澄清:

如果这是我的XML文档:

<?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>

我如何搜索type,club_type,hole_type和/或alpha。如果我想只返回以'a'开头的私人Greengrass 18hole俱乐部

1 个答案:

答案 0 :(得分:2)

  

仅返回以'a'开头的私人Greengrass 18洞球杆

在XPath中看起来像(我假设“以'a'开头”,你的意思是<alpha>就是那封信)

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

另请注意,您可以查看length返回的DOMNodeList的{​​{1}}属性。例如

DOMXPath::query()