2009-09-23 13 views
1

私はKML(xml)ドキュメントを読み込んで操作するスクリプトを書いています。以下は、私が読んでいる文書のスニペットです:Simplexml XPath stranggeness

<?xml version="1.0" encoding="UTF-8"?> 
<!-- Generated by Feature Manipulation Engine 2009 (Build 5658) --> 
<kml xmlns="http://earth.google.com/kml/2.2" xmlns:atom="http://www.w3.org/2005/Atom"> 
    <Document> 
     <name>South Australia</name> 
     <visibility>1</visibility> 
     <description><![CDATA[Statistical Local Area 2008]]></description> 
     <Folder id="kml_ft_SA_SLA08"> 
      <name>SA_SLA08</name> 
      <Placemark id="kml_1"> 
       <name>Mitcham (C) - West</name> 
       <Style> 
        <!-- style info blah blah --> 
       </Style> 
       <Polygon> 
        <!-- blah blah --> 
       </Polygon> 
      </Placemark> 

      <!-- snip lots more Placemarks --> 
     </Folder> 
    </Document> 
</kml> 

問題は、XPathを使って何かを選択することです!

$doc = new DOMDocument(); 
$doc->load('myfile.xml'); // returns true 
$xp = new DOMXPath($doc); 

$places = $xp->query("//Placemark"); 
echo $places->length;   // --> 0 ??!!?? 
$everything = $xp->query("//*"); // (so I know that the XPath isn't fully borked) 
echo $everything->length; // --> 2085 

ここでは何が起こっていますか?

+0

おそらくネームスペースと関係がありますか? –

+0

はい! 'xmlns'属性を削除すると、それはうまくいきませんでした...なぜなら... – nickf

答えて

5
<?php 
$doc = new DOMDocument(); 
$doc->load('file.xml'); // returns true 
$xp = new DOMXPath($doc); 
$xp->registerNamespace('ge', 'http://earth.google.com/kml/2.2'); 

$places = $xp->query("//ge:Placemark"); 
echo $places->length;   // --> 0 ??!!?? 
$everything = $xp->query("//*"); // (so I know that the XPath isn't fully borked) 

//echo $doc->saveXML(); 

どうやらあなたは「GE」の名前空間を登録し、そのように照会する必要があり、少なくともこれは私が数分後にグーグルで思い付いたものです。私たちは名前空間を扱っていることを時々忘れているでしょう:p

+0

私はどのノードも参照するたびに、' ge:nodeName'を使用する必要がありますか?それは迷惑です... – nickf

+0

それを回避する方法があるかもしれませんが、私はxmlの達人ではありません。 –

+0

いいえ、それを回避する方法はありません。 XPathを使用して名前空間内のXML要素または属性を照合する場合は、常にその名前空間に接頭辞を関連付けて、接頭辞をXPathで明示的に使用する必要があります。 – MiMo