PHP DOMXPath查询的意外结果

时间:2014-06-07 18:36:18

标签: php xpath

我是xml文档的结构:

<realestates:realEstates xmlns:ns2="http://rest.immobilienscout24.de/schema/platform/gis/1.0" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:common="http://rest.immobilienscout24.de/schema/common/1.0" xmlns:realestates="http://rest.immobilienscout24.de/schema/offer/realestates/1.0">
  <realEstateList>
    <typeList>
      <realEstateElement xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:offerlistelement="http://rest.immobilienscout24.de/schema/offer/listelement/1.0">
        <address>
          <postcode>31874</postcode>
        </address>
      </realEstateElement>
    </typeList>
  </realEstateList>
</realestates:realEstates>

现在我想选择所有未启动的realEstateElement-elemets,即邮政编码中的31,因为我想从文档中删除它们。

我尝试选择与此xpath-expression匹配的所有内容

typeList//realEstateElement/address[starts-with(postcode,"31")]

但我得到的东西什么都没有。如果我在开头删除typeList,我会得到所有匹配的postcode-elements而不是realEstateElement-elements。有人知道如何以简单的方式删除所有不匹配的元素吗?

谢谢!

1 个答案:

答案 0 :(得分:0)

这个XPath表达式:

//realEstateElement/address[starts-with(postcode,"31")]

在每个后代address节点中选择所有 realEstateElement个节点。这是一个包含两个步骤的XPath表达式。 last 步骤始终是您选择的步骤。前面的步骤仅为其他步骤创建上下文。每个步骤都可以有一个或多个谓词,其格式为[ *布尔表达式* ]。每个选定的节点都与其谓词进行比较,只有与之匹配的节点保存在上下文或最终结果中。

因此,如果要选择与谓词匹配的realEstateElement节点,则需要将其作为 last 步骤。路径的其余部分(address/postcode)可以在{em>谓词中使用,该谓词位于realEstateElement节点的上下文中:

//realEstateElement[starts-with(address/postcode,"31")]

这将返回包含realEstateElement元素的所有address个节点,其中postcode元素的文字内容以31开头。


注1 :如果必须进一步限制节点,可以添加更多谓词:

//realEstateElement[starts-with(address/postcode,"31")][not(starts-with(address‌​/postcode, "318"))] 

这将从 realEstateElements中选择,其中address/postcode以“31”开头,所有那些以318开头。谓词在上一个谓词或步骤创建的上下文中是有效的


注意2 :如果您需要在XPath中包含任何一个名称空间,那么名称空间将非常重要,到目前为止似乎并非如此。如果您需要这样做,您必须注册前缀,以便您可以在表达式中使用选择器:

$xmldoc->registerXPathNamespace('re', 'http://rest.immobilienscout24.de/schema/offer/realestates/1.0');

前缀不必与文档中声明的前缀匹配(如果它是默认名称空间,则可能不存在)。有了这个,你可以使用像这样的表达式:

/re:realEstates/realEstateList/typeList/realEstateElement[starts-with(address/postcode,"31")]

也使用绝对表达式选择realEstateElement