xapth表示后代或自身,同时保持文本的顺序不变


xapth for a descendant-or-self while keeping the order of text same

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

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

但是我从上面得到的数组确实改变了文本的顺序,它首先给了我所有的子体,然后是自文本,而我计划以相同的顺序精确地获得下面html结构中的所有文本,如"This text 1 This text 2 This text 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>

尝试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";
}

并按文档顺序输出CCD_ 2节点后代。但是,如果您希望例如This text 1不包含前导和/或尾随空格,则可能需要修剪这些值。

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

从技术上讲,XPath 1.0被定义为返回一个节点集,也就是说,一组没有特定顺序的节点。在实践中,我遇到的所有XPath1.0处理器都会按文档顺序返回一系列节点(可能是因为这正是XSLT1.0所要求的)。

您已经标记了问题XPath2.0,被定义为按文档顺序返回该表达式的节点序列。但是,由于您使用的是PHP,我强烈怀疑您使用的不是XPath1.0,标记只是转移注意力。

如果XPath处理器没有按文档顺序返回结果,那么可能值得将表达式重写为//div[@class="descr_id"]/descendant::text(),看看这是否有什么不同。反正它更短。