所以这个 xpath 查询让我发疯。我想要做的是搜索特定类(class)类型的高尔夫球场的 xml 文件(在这种情况下是用于与谷歌 map api 一起使用的 kml 文件)并获取每个匹配的 <Placemark> 元素,以便我可以创建一个新的 xml 对象结果,以便我可以使用新查询进一步过滤。问题是我似乎无法弄清楚如何获取每个匹配的 <Placemark> 元素

$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
  }

任何帮助将不胜感激。谢谢

最佳答案

你在查询之前没有 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 没有意义,我把它省略了。)

即使所讨论的 namespace 是 XML 文档的默认 namespace (如您的情况),也必须使用 XPath 查询中的 namespace 前缀。

元素 <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 namespace 预先注册时),无论您做什么,前者都不会匹配它们。

另请注意,您不需要使用 XML 文档中使用的相同 namespace 前缀。

假设 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");

并得到正确的结果。命名空间前缀只是一种简写。

关于php - DOM XPath 查询帮助,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/5341995/

10-12 18:56