我正在尝试选择不包含任何文本的节点。这段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>
答案 0 :(得分:1)
如果您正在寻找XPATH解决方案,请使用//RecipeSteps/(RecipeStep[string-length() = 0])
。
e.g
$path = "//RecipeSteps/(RecipeStep[string-length() = 0])";
$stepsQuery = $this->xpath->query($path);
$numResults = $stepsQuery->length;
答案 1 :(得分:0)
选择完整路径时,它可以工作:
$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())]
”也很有魅力。所以很可能你做错了什么。
答案 2 :(得分:0)
路径表达式//RecipeStep[not(text())]
和//RecipeStep[string-length() = 0]
并不一样,但是将您展示的文档作为输入,它们会返回完全相同的。在这两种情况下,都会选择一个RecipeStep
节点作为结果:
<RecipeStep number="6"/>
//RecipeStep[not(text())]
表示简单的英语:
在文档中的任何位置选择名为
RecipeStep
的元素节点,但前提是它们没有任何直接的子文本节点。
另一方面,//RecipeStep[string-length() = 0]
表示
在文档中的任何位置选择名为
RecipeStep
的元素节点,但前提是它们的字符串值(所有后代文本节点的串联)的长度等于0。
只有当配方步骤6实际上看起来像
时才会出现差异<RecipeStep number="6"><child>text</child></RecipeStep>
然后,//RecipeStep[not(text())]
仍会选择此节点,而//RecipeStep[string-length() = 0]
则不会返回任何内容。
(并且只是为了说清楚:我省略的前导//RecipeSteps
不会改变任何东西。)
因此,您的原始XPath表达式是正确的 - 并且接受的答案与原始答案完全相同。 XPath在这里没有错。