仅返回第一个结果后的PHP XPath子字符串

仅返回第一个结果后的PHP XPath子字符串,php,xml,xpath,Php,Xml,Xpath,我正在做一些HTML抓取,这一个查询让我大吃一惊。我试图从以下HTML页面结构返回一组值: <div id="product-grid"> <ul> <li><div class="price">Cash Price: $20.00</div></li> <li><div class="price">Cash Price: $30.00</div>&

我正在做一些HTML抓取,这一个查询让我大吃一惊。我试图从以下HTML页面结构返回一组值:

<div id="product-grid">
    <ul>
        <li><div class="price">Cash Price: $20.00</div></li>
        <li><div class="price">Cash Price: $30.00</div></li>
        <li><div class="price">Cash Price: $40.00</div></li>
    </ul>
</div>
我得到了所有“现金价格:$40.00”的结果列表。如果我尝试以下查询:

substring-after(id('product-grid')//p[@class="price"] , "Price: ")
我得到了正确的输出,但只得到了第一个结果。有人知道我怎样才能得到所有的结果吗

我正在运行
PHP5.3.3
libxml2.7.8
XPath
。我按如下方式调用xpath:

$xpath = new DOMXPath( $html ); 
$resultset= $xpath->query($query);

我一直在谷歌上疯狂地搜索,试图找出这一切发生的原因!请帮忙

获取列表后,必须使用子字符串

 id('product-grid')//div[@class="price"][substring-after(., 'Price: ')]
这应该行得通


编辑:这似乎有效。但是,我无法测试返回值,因为我不知道如何获取子字符串的值。你用什么?

对不起,但我认为这不可能一步到位。据我所知,XPath 1.0不支持XPath路径末尾的函数调用。答案是一样的

此外,不能将
id('product-grid')
用作第一个路径部分,因为id位于根元素上,不需要特别选择。如果示例XML只是较大XML文档的一个片段,那么可能需要使用
id()

以下工作如预期:

$xml = new DOMDocument();
$xml->loadXML('<div id="product-grid">
 <ul>
  <li><div class="price">Cash Price: $20.00</div></li>
  <li><div class="price">Cash Price: $30.00</div></li>
  <li><div class="price">Cash Price: $40.00</div></li>
</ul>
</div>');
$xpath = new DOMXPath($xml);
foreach ($xpath->query('//div[@class="price"]') as $n) {
    var_dump(substr($n->nodeValue, strpos($n->nodeValue, '$')));
}   
$xml=newDOMDocument();
$xml->loadXML('
  • 现金价格:$20.00
  • 现金价格:$30.00
  • 现金价格:$40.00
'); $xpath=newdomxpath($xml); foreach($xpath->query('//div[@class=“price”]”)作为$n){ 变量转储(substr($n->nodeValue,strpos($n->nodeValue,“$”)); }
所需的处理不能仅指定为单个XPath 1.0表达式,因为根据定义,任何需要单个字符串参数但给定一个节点集的函数都只获取该节点集的第一个(按文档顺序)节点的字符串值

此外,与XPath1.0中的XPath2.0不同,不允许将函数调用指定为位置步骤

因此,一个解决方案是发布这个XPath表达式:

substring-after((id('product-grid')//p[@class="price"])[$k], "Price: ") 
id('product-grid')//p[@class="price"]/substring-after(., "Price: ")
N
次,将每个表达式中的
$k
替换为
1,2,…,N
,其中
N
是计算另一个XPath表达式的结果:

count(id('product-grid')//p[@class="price"])
使用XPath 2.0,您可以使用这个简单而单一的表达式来实现这一点

substring-after((id('product-grid')//p[@class="price"])[$k], "Price: ") 
id('product-grid')//p[@class="price"]/substring-after(., "Price: ")

当对其求值时,将生成所需的字符串序列。

在轴上使用函数是XPath 2.0的一个功能。在标准PHP环境中可能不可用。您应该能够将其应用于谓词筛选器:
id('product-grid')//p[@class=“price”][后面的子字符串(,'price:')]。另外,示例XML显示了带有
@class
div`元素,但是示例XPath(以及您的答案)希望
p
具有
@class
@Mads-Hansen,经过后期编辑以符合1.0的要求。我用了OP的代码,所以我用了p。把它改成了div。