rapidxml:如何迭代节点?留下最后一个兄弟

问题描述:

使用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

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

下面是工作形式的最终代码:

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(); 
} 

这是虽然迭代中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