2011-03-17 95 views
3

所以這個xpath查詢讓我瘋狂。我試圖做的是搜索一個特定課程類型的高爾夫球場的xml文件(在這種情況下,一個kml文件用於谷歌地圖api),並抓住每個匹配的<Placemark>元素,以便我可以創建一個新的xml對象與結果,以便我可以進一步篩選一個新的查詢。問題是,我似乎無法弄清楚如何讓每一個匹配<Placemark>元素DOM XPath查詢幫助

$xml = '<?xml version="1.0" encoding="UTF-8"?> 
<kml xmlns="http://earth.google.com/kml/2.1"> 
    <Document> 
     <Placemark id="placemark3"> 
      <name>Test Country Club</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> 
      <styleUrl>#nineholeStyle</styleUrl> 
      <Point> 
       <coordinates>-79.285576,37.111809</coordinates> 
      </Point> 
     </Placemark> 
    </Document> 
</kml>'; 

$dom = new DOMDocument(); 
$dom->loadXML($xml); 
$xpath = new DOMXPath($dom); 

//trying to get any Placemark element where type child matches a specific query 
//in this case we want to search for Public/Daily Fee and return the placemark and everything inside it. 
$query = $xpath->query("//Placemark[type='Public/Daily Fee']/ancestor::Placemark");; 

    foreach ($query as $result) { 
    //eventually want to merge each result into new xml object to be further filtered 
    } 

任何幫助將不勝感激。謝謝

+0

[將KML文件加載到mysql/xpath和x quires中](http://stackoverflow.com/questions/5341039/loading-kml-file-in-to-mysql-xpath-and-x- quires) – 2011-03-17 16:36:42

+0

@Alejando是真的,但它沒有答案。那麼可能應該合併。 – Gordon 2011-03-17 16:37:52

回答

8

您在查詢之前沒有register the XML namespace

// register it 
$xpath->registerNamespace('kml', "http://earth.google.com/kml/2.1"); 

// and use it, too ! 
$query = $xpath->query("//kml:Placemark[kml:type='Public/Daily Fee']"); 

(在你的表達ancestor::kml:Placemark沒有任何意義,我把它忘了。)

即使有問題的命名空間是默認命名空間中的XPath查詢的命名空間前綴必須使用XML文檔的(就像你的情況一樣)。

元素<kml xmlns="http://earth.google.com/kml/2.1">相當於<kml:kml xmlns:kml="http://earth.google.com/kml/2.1">。

但是,/kml的XPath查詢不等同於/kml:kml。後者將匹配這兩個元素(當事先註冊kml名稱空間時),前者將不匹配它們,不管你做什麼。

另請注意,您不需要需要以使用XML文檔中使用的相同名稱空間前綴。

假設XML文檔是這樣的:

<kml:kml xmlns:kml="http://earth.google.com/kml/2.1"> 
    <kml:Document /> 
</kml:kml> 

,那麼你仍然可以這樣做:

$xpath->registerNamespace('foo', "http://earth.google.com/kml/2.1"); 
$query = $xpath->query("/foo:kml/foo:Document"); 

,並得到一個正確的結果。命名空間前綴只是一個簡寫。

+0

啊啊,謝謝。但最初的查詢是否正確?我沒有得到任何結果,我應該只使用$ result-> saveXML? – Jamie 2011-03-17 16:50:58

+1

@Jamie:我在我的答案中更改了XPath,我自己在一點忘記了'kml'前綴。現在應該工作。另外請注意,你根本不需要'祖先::'部分。 – Tomalak 2011-03-17 16:53:16