0

我认为的每个结果都应该在同一行。但是,对于每个 class="title",每次遇到 BR 时,结果都会被拆分为另一个数组行。结果应该都在同一行。

[html]

<td class="title">
<a href="http://boguslink">bogus title</a>....<br>
here is some text
</td>

[php]

$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)]
4

2 回答 2

2

不,它不是错误。该text()函数抓取文本节点。如果您<br />在文本之间有一个或另一个标签,那么您有必要制作多个节点。这就是 DOM 的工作方式。

好的,所以 text() 不像我想象的那样工作(所有 innerhtml 连续)。我删除了 /text() ,我只需要找出适当的 xpath,所以我没有得到链接文本。谢谢

是的,我认为您无法通过单个查询来做到这一点。基本上要获得td作为一个字符串的文本内容,您需要nodeValue. td但这也将始终包括 的文本节点a。XPath 只会根据节点选择事物,这就是它的工作原理。因此,您要么将 thetd作为节点并将所有内容作为字符串获取,要么过滤 the 的子td节点以仅获取所需的节点(最初都是 direct textNodes)。但是你必须将它们重新组装成一个字符串。

所以你有3个选择:

  1. 处理a文本并使用$theTd->nodeValue
  2. 在执行之前从 DOM 中删除a标签$theTd->nodeValue
  3. 只抓取文本节点,然后将它们重新组合成一个完整的字符串

我个人认为#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 />";
}
于 2012-06-15T15:38:40.307 回答
0

这是一个愚蠢的解决方案,但它可能对您有用...如果您不想处理文本中的中断,请在 DOM 之前用空格或 html 字符串中的任何内容替换它们。

于 2012-06-15T15:43:48.280 回答