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;
}
精彩评论