如何在xml树中反向行走节点,特别是libxml/c++
How can I reverse walk nodes in an xml tree, libxml/c++ specifically
我在一周前问过这个问题,虽然我得到了一个回复,但我从未更新过;我一开始也解释得很糟糕。所以,又来了。
<elementA>text</elementA>
<elementF>text</elementF>
<elementE>text</elementE>
<elementD>text</elementD> <-- This gets missed
<elementC>text</elementC>
<elementB>text</elementB>
<elementA>text</elementA> <-- xmlNodePtr node
<elementA>text</elementA>
<elementA>text</elementA>
<elementA>text</elementA>
<elementA>text</elementA>
那么根据上面的情况,我如何向后走到达每个节点呢?为了向前走,我会使用这个函数(还没有测试过)。也许这是一个愚蠢的问题,但在我看来,如果我简单地把它倒过来,它就会跳过上面的内容,不是吗?我觉得我错过了一些明显的东西。
htmlNodePtr find_element_by_tag(htmlNodePtr startNode, string tagname)
{
// Loop through all nodes
for (htmlNodePtr node = startNode; node != NULL; node = node->next)
{
// Only
interested in Element nodes
if(node->type == XML_ELEMENT_NODE)
{
// Compare to search tagname
if(xmlStrcasecmp(node->name, (const xmlChar*)tagname.c_str()) == 0)
{
// If found return node pointer
return node;
}
// Recursively depth walk children nodes as well
if(node->children != NULL)
{
this->find_element_by_tag(node->children);
}
}
}
// If not found return NULL pointer
return NULL;
}
一开始我看错了你的问题,所以我的第一个答案是错误的。我认为这可以工作(伪c++):
nodePtr reverse_find(nodePtr start, string tag)
{
// check current node and previous siblings
for (node = start; node != NULL; node = node->prev)
{
if (tag == node->name) { return node; }
result = find_element_by_tag(node, tag);
if (result) { return result; }
}
// not found, start looking at the parent nodes
if (node->parent)
{
if (tag == node->parent->name) { return node->parent; }
if (node->parent->prev)
{
if (tag == node->parent->prev->name) { return node->parent->prev; }
result = reverse_find(node->parent->prev, tag);
if (result) { return result; }
}
}
return NULL;
}
这是正向遍历递归解的简单转换。
考虑前向遍历的代码。它实际上是这样做的:
traverse_forward(node):
for each node sibling in forward order:
if sibling satisfies condition:
do something with child
if sibling has children:
traverse_forward(first child of sibling)
您可以反转循环的顺序,并在处理节点本身之前递归调用处理子节点,从而产生以下算法:
traverse_backward(node):
for each node sibling in reverse order:
if sibling has children:
traverse_backward(last child of sibling)
if sibling satisfies condition:
do something with child
以相反的顺序遍历兄弟节点,使用相同的循环,但使用->prev字段而不是->next字段。要获取最后一个子字段而不是第一个,您可以使用->last字段而不是->children字段。
相关文章:
- 我刚刚安装了Visual Studio,遇到了一些错误,特别是WindowsSDKDir属性未定义.可能找不到某些生成工
- 平均循环值(特别是 HSL 配色方案中的色调)
- 如何通过函数参数使用 fstream(特别是 ofstream)
- 使用 C/C++ 以外的语言构建共享库,特别是 prolog
- 是否提供了在linux上交叉编译gtkmm(特别是v3)windows库/应用程序的说明
- GCC 地址清理器 - 将库功能列入黑名单(特别是 boost::test)
- std::bind通常适用于仅移动类型,特别是std::unique_ptr
- 当我可以将RNG传递给分发时,为什么要使用variate_generator?(特别是C++和Boost)
- 了解函数特征模板的工作原理.特别是,指向成员函数的指针是怎么处理的
- 如何在C++中使用%d,特别是在DrawText()中
- 如何在SWIG包装C++代码中向目标语言(特别是Python)添加替代构造函数
- 如何将c合并到c中(特别是lex)
- C++-占位符是如何工作的(特别是在boost::type_erasure中)
- 如何在xml树中反向行走节点,特别是libxml/c++
- 当您泄漏"device"和"device context"时会发生什么 - 特别是 d3d?
- 转换到另一个库(特别是c++)
- 我迷失在提升库中(特别是boost_program_options)
- msys/MinGW,即使安装了也找不到libpng,试图编译xpdf(特别是pdftopng)
- 并发与并行——特别是在c++中
- 矢量化/优化循环,用于宽寄存器(特别是Xeon Phi)的未对齐数据访问