防止 php xpath 查询数组拆分结果


Preventing php xpath query array from splitting results

我认为每个结果都应该在同一行中。 但是,对于每个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的文本内容作为一个字符串获取,您需要tdnodeValue。但这始终包括a的文本节点。XPath 只会根据节点选择东西,这就是它的工作原理。因此,您要么将td作为节点并将所有内容作为字符串获取,要么过滤td的子节点以仅获取所需的节点(最初都是直接textNode)。但是,您必须将它们重新组合为字符串。

所以你有3个选择:

  1. 处理a文本并使用$theTd->nodeValue
  2. 在执行$theTd->nodeValue之前,请从 DOM 中删除 a 标记
  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 />";
}

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