2011-03-05 76 views
7

使用rapidxml我想通過一組節點循環,並使用我發現的最好的方法來做到這一點(來自可信任的stackoverflow,文檔似乎沒有一個例子迭代):rapidxml:如何迭代節點?留下最後一個兄弟

while (curNode->next_sibling() !=NULL) { 
    string shiftLength = curNode->first_attribute("shiftLength")->value(); 
    cout << "Shift Length " << "\t" << shiftLength << endl; 
    curNode = curNode->next_sibling();   
} 

不幸的是,在我的OSX 10.6,這是留下了最後兄弟節點 - 我猜是因爲在循環的最後一次迭代,NEXT_SIBLING被調用了兩次。我可以在這最後一個節點得到,如果我寫的,在循環之後:

cout << " LAST IS: " << curNode->first_attribute("shiftLength")->value(); 

...那是狡猾的,程序退出在該點。

第一個問題:這可能是我的設置(OSX 10.6)的一個獨特的弱點或者我編碼錯了嗎?

第二個問題:有沒有人有他們認爲是使用rapidxml遍歷未知數量的XML節點的正確方法的示例?

謝謝你們

皮特

+1

從不變式的角度考慮循環。您的所有節點都使用非NULL的下一個兄弟節點執行。對於最後一個節點,這不是真的。 – 2011-07-16 00:44:24

回答

1
while (curNode->next_sibling() !=NULL) 

這是說「雖然有一個我的工作後,剩下一個節點」。這就是爲什麼你的循環提前停止 - 當curNode是最後的兄弟姐妹,其「next_sibling」將爲NULL。這個測試應該更好的工作:

while (curNode !=NULL) 
+0

謝謝尼爾(我之前曾嘗試過這種方法,但在rapidxml.hpp中獲得了不良訪問(第1031行1.13行) - aaaaggghh我的錯誤,儘管我試圖在循環結束後查找屬性)。再次感謝。 – 2011-03-05 11:22:51

5

下面是工作形式的最終代碼:

while(curNode != NULL) { 

    string start = curNode->first_attribute("start")->value(); 
    string numStaff = curNode->first_attribute("numStaff")->value(); 
    cout << start << "\t" << numStaff << endl; 
    curNode = curNode->next_sibling(); 
} 
11

這是雖然迭代中rapidxml節點的所有子節點的正確方法:

xml_node<> *node = ... 
for (xml_node<> *child = node->first_node(); child; child = child->next_sibling()) 
{ 
    // do stuff with child 
} 
+0

如果您要選擇一個隨機節點(例如,您需要知道節點數並在偏移量X處選擇一個節點),這樣做並不方便 – 2014-12-07 23:44:31

+0

@Tomas數據結構總是存在折衷。爲了允許在分析過程中快速添加,rapidxml使用鏈接列表來表示子節點和屬性。因此,直接編號索引是不可能的。但是你必須記住,rapidxml不是關於方便,而是性能。 – kaalus 2014-12-08 20:59:34

+0

我已經寫了一個函數給你(以犧牲性能命中)'std :: vector'充滿子節點](https://gist.github.com/Darker/4b1ad792ff77a6688388)。只要文檔樹被更改,該列表就無效。 – 2014-12-08 22:48:27

相關問題