我想获取以下HTML的<p>
和<h3>
标记之间的所有文字
<div class="bodyText">
<p>
<div class="articleBox articleSmallHorizontal channel-32333770 articleBoxBordered alignRight">
<div class="one">
<a href="url" class="img"><img src="url" alt="bar" class="img" width="80" height="60" /></a>
</div>
<div class="two">
<h4 class="preTitle">QIEZ-Lieblinge</h4>
<h3 class="title"><a href="url" title="ABC" onclick="cmsTracking.trackClickOut({element:this, channel : 32333770, channelname : 'top_listen', content : 14832081, callTemplate : '_htmltagging.Text', action : 'click', mouseevent : event});">
Prominente Gastronomen </a></h3>
<span class="postTitle"></span>
<span class="district"><a href="http://www.qiez.de/berlin/top-listen" title="TOP-LISTEN in Berlin">Berlin</a></span> </div>
<div class="clear"></div>
</div>
I want this TEXT</p>
<h3>I want this TEXT</h3>
<p>I want this TEXT</p>
<p>
<div class="inlineImage alignLeft">
<div class="medium">
<img src="http://images03.qiez.de/Restaurant+%C3%96_QIEZ.jpg/280x210/0/167.231.886/167.231.798" width="280" height="210" alt="Schöne Lage: das Restaurant Ø. (c)QIEZ"/>
<span class="caption">
Schöne Lage: das Restaurant Ø. (c)QIEZ </span>
</div>
</div>I want this TEXT</p>
<p>I want this TEXT</p>
<p>I want this TEXT<br /> </p>
<blockquote><img src="url" alt="" width="68" height="68" />
"Eigentlich nur drei Worte: Ich komme wieder."<span class="author">Tina Gerstung</span></blockquote>
<div class="clear"></div>
</div>
我想要所有“我想要这个文字”。我使用了xpath查询
//div[contains(@class,'bodyText')]/*[local-name()='p' or local-name()='h3']
但如果<p>
标记后面跟着任何其他标记
答案 0 :(得分:1)
看起来你的p元素中包含div元素是无效的并且弄乱了东西。如果在循环中使用var_dump,您可以看到它确实拾取了节点,但nodeValue为空。
对html进行快速而肮脏的修复是将包含在p元素中的第一个div包装在一个范围内。
<span><div class="articleBox articleSmallHorizontal channel-32333770 articleBoxBordered alignRight">...</div></span>
更好的解决方法是将div元素放在段落之外。
如果您使用脏的变通方法,则需要更改您的查询:
$xpath->query("//div[contains(@class,'bodyText')]/*[local-name()='p' or local-name()='h3']/text()");
如果您无法控制源html。您可以复制html并删除有问题的div:
$nodes = $xpath->query("//div[contains(@class,'articleBox')]");
$node = $nodes->item(0);
$node->parentNode->removeChild($node);
使用simple_html_dom可能更容易。也许你可以试试这个:
include('simple_html_dom.php');
$dom = new simple_html_dom();
$dom->load($html);
foreach($dom->find("div[class=bodyText]") as $parent) {
foreach($parent->children() as $child) {
if ($child->tag == 'p' || $child->tag == 'h3') {
// remove the inner text of divs contained within a p element
foreach($dom->find('div') as $e)
$e->innertext = '';
echo $child->plaintext . '<br>';
}
}
}
答案 1 :(得分:0)
这是混合内容。根据定义元素位置的内容,您可以使用许多因素。在这个cse中,可能只需选择所有文本节点即可:
//div[contains(@class, 'bodyText')]/(p | h3)/text()
如果处理器中不允许路径位置中的union运算符,那么您可以像以前一样使用语法,或者在我看来稍微简单一些:
//div[contains(@class, 'bodyText')]/*[local-name() = ('p', 'h3')]/text()