繁体   English   中英

选择多个节点块,包括XPath 1.0的开始和结束节点

[英]Select multiple blocks of nodes including the start and end nodes with XPath 1.0

以下是我的XML的简化版本:

<div><p class="start">1</p></div>
<div><p class="data">2</p></div>
<div><p class="data">3</p></div>
<div><p class="end">4</p></div>
<div><p class="data">5</p></div>
<div><p class="start">6</p></div>
<div><p class="data">7</p></div>
<div><p class="end">8</p></div>

这是我的代码的简化版本:

<?php
...
$start_nodes = $finder->query('//div[p/@class="start"]');
foreach ($start_nodes as $node) {
  $data_nodes = $finder->query('following-sibling::div[p/@class="end"][1]/preceding-sibling::*', $node);
  ...
}

我不知道如何选择<div><p class="start"/></div>节点,下一个<div><p class="end"/></div>节点和所有节点在两者之间。 在上面的示例中,我想得到1-4,然后是6-8,然后跳过5。

我在PHP中使用XPath 1.0,而不是XLST。

这是一种可能的方式:

$start_nodes = $finder->query('//div[p/@class="start"]');
foreach ($start_nodes as $node) {
    $count = $finder->evaluate('count(preceding-sibling::div[p/@class="start"])', $node)+1;
    echo 'start '. $count .' : <br>';
    $start = 'self::*';
    $end = 'following-sibling::div[p/@class="end"][1]';
    $inbetween = 'following-sibling::div[p/@class="end"][1]/preceding-sibling::*[count(preceding-sibling::div[p/@class="start"])='.$count.']';
    $data_nodes = $finder->query($start.' | '.$inbetween.' | '.$end, $node);
    foreach($data_nodes as $d){
        echo $d->nodeValue .", ";
    }
    echo "<br><br>";
}

上面的$data_nodes是三个单独的xpath表达式的并集( | )的结果; 第一个xpath用于选择'start element'( $start ),第二个xpath用于选择'end element'( $end ),最后一个用于在start和end元素之间选择元素( $inbetween )。

演示

输出:

start 1 :
1, 2, 3, 4,

start 2 :
6, 7, 8,

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM