PHP XPath子字符串——在只返回第一个结果之后


PHP XPath substring-after only returning first result

我正在做一些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>

我试图在列表中返回"$20.00"价格。如果我使用以下XPath:

id('product-grid')//p[@class="price"] 

我得到所有"现金价格:$40.00"的结果列表。如果我尝试以下查询:

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

得到正确的输出,但只得到第一个结果。有人知道我怎么得到所有结果吗?

我运行PHP5.3.3libxml 2.7.8XPath。我像这样调用xpath:

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

我一直在疯狂地搜索,试图找出为什么会发生这种情况!请帮助!

对不起,但我不认为这是可能的一步。据我所知,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, '$')));
}   

您必须在获得列表后使用子字符串

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

应该可以。

EDIT:这似乎正在工作。然而,我不能测试返回值,因为我不知道如何获得子字符串的值。

所需的处理不能仅仅指定为单个XPath 1.0表达式,因为根据定义,任何期望单个字符串参数但给定一个节点集的函数,都取该节点集的第一个(按文档顺序)节点的字符串值。

另外,与XPath 2.0不同的是,XPath 1.0不允许将函数调用指定为定位步骤。

因此,一种解决方案是发出这个XPath表达式:
substring-after((id('product-grid')//p[@class="price"])[$k], "Price: ") 

N次,用1,2,..., N替换每个表达式中的$k,其中N是对另一个XPath表达式求值的结果:

count(id('product-grid')//p[@class="price"])

使用XPath 2.0可以使用这个简单的表达式:

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