我认为每个结果都应该在同一行中。 但是,对于每个class="title",每次遇到BR时,结果都会拆分为另一个数组行。 结果应该都在同一行中。
[网页]
<td class="title">
<a href="http://boguslink">bogus title</a>....<br>
here is some text
</td>
[菲律宾文]
$dom = new DOMDocument();
$dom->loadHTML($html);
$xpath = new DOMXPath($dom);
$result = $xpath->query('//td[@class="title"]/text()');
foreach ($result as $result_row)
{
echo $i.":".$result_row->nodeValue."<br />";
$i++;
}
[输出]
0: ....
1: here is some text
何时输出应为
[输出]
0: ....here is some text
这是一个错误吗? 如果不是,那么我如何防止 class="title" 结果被拆分为单独的行并同时保持我的代码快速精简,如上所示?
编辑:
好吧,不是/text() 的错误和行为。 我能够通过简单地从 xpath 表达式中删除/text() 来获取该类的所有内部文本。它只是想弄清楚此时如何排除链接文本,所以我只得到"....这是一些文字"。
所以我需要一个排除链接文本的表达式。第一次失败的尝试是。
//td[@class="title"][not(a)]
//td[@class="title"][not(self::a)]
//td[@class="title"][not(@href)]
不,这不是一个错误。text()
函数抓取文本节点。如果您在文本之间有一个<br />
或其他标签,那么您必须创建多个节点。这就是 DOM 的工作方式。
好的,所以text()不能像我想象的那样工作(所有innerhtml 连续)。我删除了/text(),我只需要弄清楚 适当的 xpath,所以我没有得到链接文本。感谢
是的,我认为您无法通过单个查询做到这一点。基本上,要将td
的文本内容作为一个字符串获取,您需要td
的nodeValue
。但这始终包括a
的文本节点。XPath 只会根据节点选择东西,这就是它的工作原理。因此,您要么将td
作为节点并将所有内容作为字符串获取,要么过滤td
的子节点以仅获取所需的节点(最初都是直接textNode
)。但是,您必须将它们重新组合为字符串。
所以你有3个选择:
- 处理
a
文本并使用$theTd->nodeValue
- 在执行
$theTd->nodeValue
之前,请从 DOM 中删除a
标记 - 仅抓取文本节点,然后将它们重新组合成一个完整的字符串
我个人认为#3是最好的选择,你只需要重新设计你的代码......
$tdNodes = $xpath->query('//td[@class="title"]');
foreach ($tdNodes as $i => $td)
{
$text = $xpath->query('./text()', $td);
$textStr = '';
foreach($text as $str)
{
$textStr .= $str->nodeValue;
}
echo $i.":".$textStr."<br />";
}
这是一个愚蠢的解决方案,但它可能对你有用......如果您不想处理文本中的中断,请在 DOM 之前用空格或 html 字符串中的任何内容替换它们。