【问题标题】:Select multiple blocks of nodes including the start and end nodes with XPath 1.0使用 XPath 1.0 选择多个节点块,包括起始节点和结束节点
【发布时间】:2015-06-13 13:03:35
【问题描述】:

以下是我的 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);
  ...
}

我不知道如何选择&lt;div&gt;&lt;p class="start"/&gt;&lt;/div&gt; 节点、下一个&lt;div&gt;&lt;p class="end"/&gt;&lt;/div&gt; 节点以及它们之间的所有节点。在上面的例子中,我想得到 1-4,然后是 6-8,然后跳过 5。

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

【问题讨论】:

  • 我认为这绝不是 :( 你应该扫描节点直到 &lt;div&gt;&lt;p class="end"

标签: php xpath


【解决方案1】:

这是一种可能的方式:

$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),第二个用于选择“结束元素”($end),最后一个用于选择开始和结束元素之间的元素($inbetween)。

Demo

输出:

start 1 :
1, 2, 3, 4,

start 2 :
6, 7, 8,

【讨论】:

  • 谢谢!我将self::* 更改为.,它似乎工作正常!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-06-02
  • 1970-01-01
  • 2011-02-26
  • 1970-01-01
  • 2013-11-28
  • 1970-01-01
相关资源
最近更新 更多