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节点的正确方法的示例?
谢谢你们
皮特
while (curNode->next_sibling() !=NULL)
这是说“虽然有一个我的工作后,剩下一个节点”。这就是为什么你的循环提前停止 - 当curNode
是最后的兄弟姐妹,其“next_sibling
”将为NULL。这个测试应该更好的工作:
while (curNode !=NULL)
谢谢尼尔(我之前曾尝试过这种方法,但在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
}
如果您要选择一个随机节点(例如,您需要知道节点数并在偏移量X处选择一个节点),这样做并不方便 – 2014-12-07 23:44:31
@Tomas数据结构总是存在折衷。为了允许在分析过程中快速添加,rapidxml使用链接列表来表示子节点和属性。因此,直接编号索引是不可能的。但是你必须记住,rapidxml不是关于方便,而是性能。 – kaalus 2014-12-08 20:59:34
我已经写了一个函数给你(以牺牲性能命中)'std :: vector'充满子节点](https://gist.github.com/Darker/4b1ad792ff77a6688388)。只要文档树被更改,该列表就无效。 – 2014-12-08 22:48:27
从不变式的角度考虑循环。您的所有节点都使用非NULL的下一个兄弟节点执行。对于最后一个节点,这不是真的。 – 2011-07-16 00:44:24