PHP DomXPath 未选择空文本节点

PHP DomXPath not selecting empty text nodes

我正在尝试 select 不包含任何文本的节点。这段 php 代码跳过示例 xml 中的空节点。但是,当我尝试使用在线测试仪(例如 http://freeformatter.com/xpath-tester.html)时,它没有任何问题。

这是 PHP 的事情吗?

我的php代码:

    $path = "//RecipeSteps/RecipeStep[not(text())]";
    $stepsQuery = $this->xpath->query($path);
    $numResults = $stepsQuery->length;

我的样本xml:

<?xml version="1.0" encoding="utf-8"?>
<Recipes>
    <RecipeSteps>
      <RecipeStep number="1">Dummy content</RecipeStep>
      <RecipeStep number="2">Dummy content</RecipeStep>
      <RecipeStep number="3">Dummy content</RecipeStep>
      <RecipeStep number="4">Dummy content</RecipeStep>
      <RecipeStep number="5">Dummy content</RecipeStep>
      <RecipeStep number="6"></RecipeStep>
      <RecipeStep number="7">Variations</RecipeStep>
      <RecipeStep number="8">Some variation content..</RecipeStep>
    </RecipeSteps>
</Recipes>

如果您正在寻找 XPATH 解决方案,请使用 //RecipeSteps/(RecipeStep[string-length() = 0])。 例如

$path = "//RecipeSteps/(RecipeStep[string-length() = 0])";
$stepsQuery = $this->xpath->query($path);
$numResults = $stepsQuery->length;

选择完整的路径时,它可以正常工作:

$xmlString = '<?xml version="1.0" encoding="utf-8"?>
<Recipes>
    <RecipeSteps>
      <RecipeStep number="1">Dummy content</RecipeStep>
      <RecipeStep number="2">Dummy content</RecipeStep>
      <RecipeStep number="3">Dummy content</RecipeStep>
      <RecipeStep number="4">Dummy content</RecipeStep>
      <RecipeStep number="5">Dummy content</RecipeStep>
      <RecipeStep number="6"></RecipeStep>
      <RecipeStep number="7">Variations</RecipeStep>
      <RecipeStep number="8">Some variation content..</RecipeStep>
    </RecipeSteps>
</Recipes>';

$dom = new DOMDocument();
$dom->loadXML($xmlString);
$xpath = new DOMXpath($dom);
# it works also well: //RecipeSteps/RecipeStep[not(text())]
$query = $xpath->query('//Recipes/RecipeSteps/RecipeStep[not(text())]');
//returns "6"
print 'RecipeStep number: ' . $query->item(0)->getAttribute('number');

此外,选择“//RecipeSteps/RecipeStep[not(text())]”也很有效。所以很可能你做错了什么。

路径表达式//RecipeStep[not(text())]//RecipeStep[string-length() = 0]的意思不一样,但是把你显示的文档作为输入,它们return完全一样.在这两种情况下,一个 RecipeStep 节点被 selected 作为结果:

<RecipeStep number="6"/>

//RecipeStep[not(text())] 用简单的英语表示:

Select element nodes called RecipeStep anywhere in the document, but only if they do not have any immediate child text nodes.

另一方面,//RecipeStep[string-length() = 0]表示

Select element nodes called RecipeStep anywhere in the document, but only if the length of their string value (the concatenation of all descendant text nodes) is equal to 0.

只有当第 6 步的食谱看起来像这样时,差异才会明显

<RecipeStep number="6"><child>text</child></RecipeStep>

那么,//RecipeStep[not(text())] 仍然会 select 这个节点,而 //RecipeStep[string-length() = 0] 不会 return 任何东西。

(为了清楚起见:我省略的前导 //RecipeSteps 不会改变任何东西。)

因此,您原来的 XPath 表达式是正确的 - 并且接受的答案与您原来的答案完全相同。 XPath 在这里没有错。