好的,我一直在研究一个类来遍历html doc中的所有节点并返回我需要的数据。这很简单,我已经在Bash中实现了这一点,但现在我正在尝试将其移植到C ++中。
我从libxml网站上的示例开始,但是我逐个节点地逐步完成了这个功能,我无法理解它是如何工作的。
这是功能:
static void
print_element_names(xmlNode * a_node)
{
xmlNode *cur_node = NULL;
for (cur_node = a_node; cur_node; cur_node = cur_node->next) {
if (cur_node->type == XML_ELEMENT_NODE) {
printf("node type: Element, name: %s\n", cur_node->name);
}
print_element_names(cur_node->children);
}
}
基本上,这个函数将节点分配给指针,并开始循环遍历所有兄弟节点,但如果当前节点有子节点,它会调用该函数并从该子节点重新开始。这一切都是可以理解的。
因此它推动了doc结构,但它如何导航结构?
xmlNode->子节点在找到NULL时会返回下一个父节点吗?据我所知,这不是真的,但我无法弄清楚这是如何运作的。
我成功地创建了一个类来做我想要的,但它比这复杂得多,大约10行。我实际上必须检查下一个节点是否为空,如果它有子节点则向下导航或向后导航,如果没有则向下导航到下一个节点。
这个例子更简单,我想了解如何使我的代码更好。
答案 0 :(得分:2)
答案 1 :(得分:0)
迭代地解决问题本质上是树遍历。您将需要一个堆栈来完成此任务。堆栈可能最容易实现为单链表。
// interface to be implemented
typedef void* Stack;
Stack stack_new(); // creates a new stack
void stack_add(Stack stack, xmlNode *element); // adds an element to the stack
int stack_size(); // returns the number of elements currently in the stack
xmlNode* stack_remove(Stack stack); // pops an element from the stack
void stack_free(Stack stack); // frees up resources used by the stack
// printing code
static void print_element_names(xmlNode *a_node)
{
Stack stack = stack_new();
stack_add(stack, a_node);
while(stack_size(stack))
{
xmlNode *cur_node = stack_remove(stack);
if(cur_node->children) stack_add(cur_node->children);
xmlNode *iter_node = NULL;
for (iter_node = cur_node; iter_node; iter_node = iter_node->next)
{
if (iter_node->type == XML_ELEMENT_NODE)
printf("node type: Element, name: %s\n", iter_node->name);
}
}
stack_free(stack);
}