【问题标题】:Why does xpath find excluded nodes again?为什么 xpath 会再次找到排除的节点?
【发布时间】:2017-06-29 06:15:19
【问题描述】:

考虑这个页面:

<n1 class="a">
  1
</n1>
<n1 class="b">
  <b>bold</b>
  2
</n1>

如果我首先使用class="a" 选择第一个n1,我应该排除第二个n1,这确实是这样:

library(rvest)
b_nodes = read_html('<n1 class="a">1</n1>
<n1 class="b"><b>bold</b>2</n1>') %>% 
  html_nodes(xpath = '//n1[@class="b"]')
b_nodes
# {xml_nodeset (1)}
# [1] <n1 class="b"><b>bold</b>2</n1>

但是,如果我们现在使用这个“子集”页面:

b_nodes %>% html_nodes(xpath = '//n1')
# {xml_nodeset (2)}
# [1] <n1 class="a">1</n1>
# [2] <n1 class="b"><b>bold</b>2</n1>

1 节点是如何“重新发现”的??

注意:我知道如何使用两个单独的 xpath 来获得我想要的东西。这是一个关于为什么“子集”没有按预期工作的概念性问题。我的理解是b_nodes 应该完全排除第一个节点——b_nodes 对象甚至不应该知道该节点存在。

【问题讨论】:

  • 更简单的说明:b_nodes %&gt;% html_nodes(xpath = '//n1')。看起来它的设计不是为了链接/始终指向原始对象。
  • @Frank 好点,我想我已经尝试过了,但没有成功。我会编辑它

标签: r xpath rvest xml2


【解决方案1】:
html_nodes(xpath = '//n1')

///descendant-or-self::n1的缩写,当前节点是整个文档

改成.//n1.表示当前节点是你之前选择的那个

【讨论】:

  • @MichaelChirico 当您使用// 时,您将查询整个文档,无论您是哪个子节点。
  • 我仍然觉得奇怪的是其他节点没有被第一个表达式删除。即,对我来说,“整个文档”应该只是 &lt;n1 class="b"&gt;...&lt;/n1&gt;,这是从 b_nodes 显示的内容。
【解决方案2】:

我不知道您要做什么,但是,您为什么不尝试使用 foreach 遍历节点?我的意思是:

$XML = read_html('
<n1s>
<n1 class="a">1</n1>
<n1 class="b"><b>bold</b>2</n1></n1s>') %>%


$valueA = '';
$valueB = '';    
foreach ($XML->xpath('//n1') as $n1) {
        switch ((string)$n1['class']){
              case 'a':
                    $valueA = $XML->n1;
                     break;
              case 'b':
                    $valueB = $XML->n1;
                     break;
        }
    }

我希望这可以帮助你。 问候!

【讨论】:

  • 查看编辑,这不是怎么做的问题
猜你喜欢
  • 2018-11-06
  • 2015-06-30
  • 1970-01-01
  • 2012-05-02
  • 1970-01-01
  • 2016-07-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多