我使用以下代码作为dom文档的输入
<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] =&gt; [1] =&gt;#20,267在Kindle商店支付([2] =&gt;)
我该如何解决这个问题?
答案 0 :(得分:1)
//li[@id='SalesRank']/text()
是否适合您?
更新1
如果您想要的文字始终位于该位置,那么
substring-before(normalize-space(//li[@id='SalesRank']/text()[2]), ' (')
将返回
#20,267 Paid in Kindle Store
这使用normailize-space
去除无关的空白区域,并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我认为。)
希望这有帮助,
答案 1 :(得分: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);