用于后代或自我的xpath,同时保持文本的顺序相同

时间:2013-11-17 18:08:18

标签: php xpath xpath-2.0

我试图使用xpath从下面的html结构中提取文本, 我正在使用的xpath表达式是

'//div[@class="descr_id"]/descendant-or-self::*/text()'

但是我从上面得到的数组,确实改变了文本的顺序,它首先给了我所有的后代然后自我文本,而我计划完全以相同的顺序获得下面的html结构中的所有文本“本文1本文2本文3 .........”。

<div class="descr_id">
         This text 1
         <a href="www.example.com">This text 2</a>
         This text 3 
         <a href="www.example2.com">This text 4</a>
         This text main 5
         <ul>
           <li>
           This text 6</li>
           <li>
           This text 7</li>
        </ul>
    </div>

2 个答案:

答案 0 :(得分:0)

尝试http://sandbox.onlinephpfunctions.com/code/99f45357f08f3833773ba7ada0f5fbf6a4b7180c

$html = <<<EOD
<div class="descr_id">
         This text 1
         <a href="www.example.com">This text 2</a>
         This text 3 
         <a href="www.example2.com">This text 4</a>
         This text main 5
         <ul>
           <li>
           This text 6</li>
           <li>
           This text 7</li>
        </ul>
    </div>
EOD;

$doc = new DOMDocument();
$doc->loadHTML($html);

$xpath = new DOMXPath($doc);

$textNodes = $xpath->query('//div[@class="descr_id"]//text()[normalize-space()]');


foreach ($textNodes as $text)
{
  echo "$text->nodeValue\n";
}

并按文档顺序输出text个节点后代。您可能希望修改值但是如果您需要,例如This text 1没有前导和/或尾随空格。

答案 1 :(得分:0)

你没有清楚地解释你实际得到的输出。

从技术上讲,XPath 1.0被定义为返回一个节点集 - 即一组没有特定顺序的节点。实际上,我遇到的所有XPath 1.0处理器都按文档顺序返回一系列节点(可能是因为这是XSLT 1.0所要求的)。

您已经标记了XPath 2.0的问题,其中 被定义为按此文档顺序返回此表达式的节点序列。但是,由于您使用的是PHP,我强烈怀疑您使用的是XPath 1.0,而且标签是红色的鲱鱼。

如果你的XPath处理器没有以文档顺序返回结果,那么可能值得将表达式重写为//div[@class="descr_id"]/descendant::text()以查看是否有任何区别。无论如何它都更短。