2012-02-11 101 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);