the original code example
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);
}
}
So I checked the xmlNode structure and find out the parent node is the useful hint to traverse the xml node tree.
- Process the current node first.
- Check the node if there is any children node and yes, process the children node.
- Check the node if there is any next node and yes, process the next node.
- If there is no children and next node,
- check if there is any parent node and yes, go back to the parent node
- When in the parent node, because it should be processed in step 0, check if there is any next node.
- If there is a next node, repeat step 3.
- If there is no any next node, repeat step 4.
- Finally there is no next and parent node, the node should be the XML_DOCUMENT_NODE.
{
for (; indent; --indent) {
putchar(' ');
putchar(' ');
}
}
int getNextNode( xmlNode **pCurr, int *deepth )
{
xmlNode *curr = *pCurr;
if ( curr->children!=NULL ) {
/* Move to the children node.
*/
curr = curr->children;
*deepth += 1;
} else if ( curr->next==NULL && curr->parent) {
/* Go back to the parent node.
then go to the next node of the parent node or
go to the parent node of the parent node if there is no any next node behind.
if there is no any parent node, it should be the XML_DOCUMENT_NODE.
*/
curr = curr->parent;
*deepth -= 1;
while ( curr->next==NULL && curr->parent!=NULL ) {
curr = curr->parent;
*deepth -= 1;
}
if ( curr->next!=NULL ) {
curr = curr->next;
} else {
/* It should be XML_DOCUMENT_NODE.
*/
curr = NULL;
}
} else {
curr = curr->next;
}
*pCurr = curr;
}
void process_node(xmlNode *pNode)
{
xmlNode *curr=NULL;
int indent=0;
if ( !pNode ) {
printf("No Node exist\n");
return;
}
for ( curr=pNode ; curr ; getNextNode(&curr, &indent)) {
if (curr->type == XML_ELEMENT_NODE) {
do_indent(indent);
printf("node type: Element, name: %s", curr->name);
if ( curr->properties ) {
process_attr(curr->properties);
}
printf("\n");
} else if ( curr->type==XML_TEXT_NODE ) {
do_indent(indent);
printf("node type: Text, name: %s\n", curr->content);
}
}
}
No comments:
Post a Comment