2017-02-10 64 views
3

考慮這個頁面:爲什麼xpath會再次找到排除的節點?

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

如果我先選擇第一n1使用class="a",我應該是不包括第二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怎麼點頭e得到「重新發現」?

注意:我知道如何用兩個單獨的xpath獲得我想要的。這是一個關於爲什麼「子集」沒有按預期工作的概念性問題。我的理解是,b_nodes應該已經排除了第一個節點--對象應該不知道該節點存在。

+1

更簡單的例子:'b_nodes%>%html_nodes(xpath ='// n1')'。看起來它不是被設計成鏈接/始終指向原始對象。 – Frank

+0

@Frank好點,我以爲我試過,並沒有奏效。我將在 – MichaelChirico

回答

1
html_nodes(xpath = '//n1') 

//是短期的/descendant-or-self::n1,當前節點是整個文檔

將其更改爲.//n1.意味着當前節點是你以前

+0

@MichaelChirico中編輯它,當你使用'//'查詢整個文檔時,不管你是哪個子節點。 –

+0

我仍然覺得奇怪的是其他節點沒有被第一個表達式刪除。即「整個文檔」對我來說應該只是' ...',這是'b_nodes'顯示的內容。 – MichaelChirico

0

選擇了什麼我不你要做什麼,但是,你爲什麼不試着用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; 
     } 
    } 

我希望這可以幫助你。 關心!

+0

看編輯,這不是如何做某事的問題 – MichaelChirico