2012-02-11 52 views
1

数据我使用下面的代码作为输入到DOM文档滤波器提取使用XPath

<li id="SalesRank"> 
<b>Amazon Best Sellers Rank:</b> 
#20,267 Paid in Kindle Store (
<a href="http://www.amazon.com/gp/bestsellers/digital-text/ref=pd_dp_ts_kstore_1/190-9295683-0277616">See Top 100 Paid in Kindle Store</a> 
) 
<ul class="zg_hrsr"> 
<li class="zg_hrsr_item"> 
<span class="zg_hrsr_rank">#15</span> 
<span class="zg_hrsr_ladder"> 
in 
<a href="http://www.amazon.com/gp/bestsellers/digital-text/ref=pd_zg_hrsr_kstore_1_1">Kindle Store</a> 
> 
<a href="http://rads.stackoverflow.com/amzn/click/154606011">Kindle eBooks</a> 
> 
<a href="http://rads.stackoverflow.com/amzn/click/157325011">Nonfiction</a> 
> 
<a href="http://rads.stackoverflow.com/amzn/click/292975011">Lifestyle & Home</a> 
> 
<a href="http://rads.stackoverflow.com/amzn/click/156699011">Home & Garden</a> 
> 
<a href="http://rads.stackoverflow.com/amzn/click/156828011">Gardening & Horticulture</a> 
> 
<b> 
<a href="http://rads.stackoverflow.com/amzn/click/156847011">Greenhouses</a> 
</b> 
</span> 
</li> 
<li class="zg_hrsr_item"> 
<span class="zg_hrsr_rank">#26</span> 
<span class="zg_hrsr_ladder"> 
in 
<a href="http://www.amazon.com/gp/bestsellers/digital-text/ref=pd_zg_hrsr_kstore_2_1">Kindle Store</a> 
> 
<a href="http://rads.stackoverflow.com/amzn/click/154606011">Kindle eBooks</a> 
> 
<a href="http://rads.stackoverflow.com/amzn/click/157325011">Nonfiction</a> 
> 
<a href="http://rads.stackoverflow.com/amzn/click/292975011">Lifestyle & Home</a> 
> 
<a href="http://rads.stackoverflow.com/amzn/click/156699011">Home & Garden</a> 
> 
<a href="http://rads.stackoverflow.com/amzn/click/156828011">Gardening & Horticulture</a> 
> 
<b> 
<a href="http://rads.stackoverflow.com/amzn/click/156849011">House Plants</a> 
</b> 
</span> 
</li> 
</ul></li> 

我使用以下XPath查询以提取与数据的textContent ..

$xpath_cat->query('//li[@id="SalesRank"]'); 

可以检查输出,它包括所有li标签中包含的数据与id=salrsrank...,而我只想得到#20,267 paid in kindle store..

因此所需的输出

#20,267在Kindle商店

付费如何修改我的XPath来获得所需要的输出?

在代码

更新我试图溶液下文提供和使用的XPath

$xpath_cat->query('//li[@id="SalesRank"]/text()'); 

但现在,输出是

([0] => [1 ] =>#20,267在Kindle商店支付([2] =>)

我该如何解决这个问题?

+0

仍然在失败...... – 2012-02-12 21:04:12

回答

1

请问//li[@id='SalesRank']/text()是否适合您?

更新1

如果你想总是会在该位置的文字,然后

substring-before(normalize-space(//li[@id='SalesRank']/text()[2]), ' (') 

将返回

#20,267 Paid in Kindle Store 

这使用normailize-space剥离掉无关whitepspace,和substring-before选择第一次出现之前的所有文本“(”。

这个问题会容易得多,如果你能在自己的节点获取目标文本,如:

<b>Amazon Best Sellers Rank:</b> 
<span>#20,267 Paid in Kindle Store</span> (
<a href="http://www.amazon.com/gp/bestsellers/digital-text/ref=pd_dp_ts_kstore_1/190-9295683-0277616">See Top 100 Paid in Kindle Store</a> 
) 

<span/>对渲染无影响,可以专门选择您想要的文字。

如果第二个解决方案在所有情况下都不能正常工作,并且您现在无法自己获取目标文本,那么您的将具有依赖于主机语言中的某些后处理(PHP我假设) 。

希望这有助于

+0

我试过了,t他计数的结果应该是1(显然,我只需要第一个文本()),但使用此代码的结果数为3。 – 2012-02-11 22:09:02

+0

@NewBee我添加了一个更具体的解决方案,将原始发布的输入格式设置为100%。 – 2012-02-13 02:30:07

+0

我应该在xpath查询中使用它吗? – 2012-02-14 16:27:29

1

让我们假设$element是包含DOMElement<li id="SalesRank">...

如果你做这样的事情:

foreach($element->childNodes as $node){ 
    echo get_class($node) . "\n"; 
    // Print content too for debug: 
    // echo $node->nodeValue . "\n"; 
} 

你应该得到类似的结果:

DOMText // \n 
DOMElement // <b>Amazon Best Sellers Rank:</b> 
DOMText // #20,267 Paid in Kindle Store (\n 
DOMElement // <a ... 
... 

所以$element->childNodes->item(2)->nodeValue应该包含你的字符串(做你的功课,检查每个迭代,检查每个元素的文档)。

比你可以简单地得到弦,直到第一(

$text = $element->childNodes->item(2)->nodeValue; 
$pos = strpos($text, '(') - 2; // Add handling for no occurance 
return substr($text, 0, $pos); 

或者你可以遍历低谷所有子节点并检查它的飞行

foreach($element->childNodes as $node){ 
    // Example, rather use regexp with preg_match 
    if((get_class($node) == 'DOMText') 
     && (strncmp($node->nodeValue, "\n#", 2) == 0)){ 
     // Tadaaa 
     break; 
    } 
} 

或者,如果你想解决方案,将杀死几只小猫:

preg_match('~(#([\d,]+) ([^<>(]+))~', $element->nodeValue, $match);