我正在进行一些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.3
正在libxml 2.7.8
XPath
$xpath = new DOMXPath( $html );
$resultset= $xpath->query($query);
。我按如下方式调用xpath:
{{1}}
我一直在谷歌搜索疯狂试图找出为什么会发生这种情况!请帮忙!
答案 0 :(得分:1)
获取列表后必须使用子字符串。
id('product-grid')//div[@class="price"][substring-after(., 'Price: ')]
这应该有用。
编辑:这似乎有效。但是我无法测试返回值,因为我不知道如何获取子字符串值。你用什么?
答案 1 :(得分:1)
抱歉,但我认为这不可能一步到位。据我所知,XPath 1.0不支持XPath路径末尾的函数调用。答案here表示相同。
此外,您不能使用 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, '$')));
}
答案 2 :(得分:1)
无法将所需的处理指定为单个XPath 1.0表达式,因为根据定义,任何需要单个字符串参数但给定节点集的函数都会获取第一个字符串的字符串值仅(按文档顺序)此节点集的节点。
此外,与XPath 1.0中的XPath 2.0不同,不允许将函数调用指定为位置步骤。
因此,一种解决方案是发出此XPath表达式:
substring-after((id('product-grid')//p[@class="price"])[$k], "Price: ")
N
次,用$k
替换每个表达式中的1,2,..., N
,其中N
是评估另一个XPath表达式的结果:
count(id('product-grid')//p[@class="price"])
使用XPath 2.0可以使用这个简单的单个表达式:
id('product-grid')//p[@class="price"]/substring-after(., "Price: ")
在评估时产生完全符合要求的字符串序列。