2013-04-04 78 views
2

好的我一直在研究一個類來遍歷html文檔中的所有節點,並返回我需要的數據。這非常簡單,我已經在Bash中實現了這一點,但現在我試圖將其移植到C++中。C++ libxml xmlNode-> children

我開始在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); 
    } 
} 

因此,基本上,這個功能需要一個節點將其分配給一個指針,並通過所有兄弟節點開始循環,但如果當前節點有孩子,它會調用函數並重新開始該子節點。這完全是可以理解的。

因此,它驅動了文檔結構,但它如何導航回結構?

xmlNode-> children在發現NULL時返回下一個父節點嗎?據我所知,這不是事實,但我無法弄清楚這是如何工作的。

我成功地創建了一個類來完成我想要的任務,但它比這個複雜得多,大約需要10行。實際上,我必須檢查下一個節點是否爲空,並且如果它有子節點,則向下導航,如果沒有導航,則導航到下一個節點。

這個例子非常簡單,我想了解如何讓我的代碼更好。

回答

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); 
} 
+1

這非常有趣。沒有想過使用堆棧。嘗試編譯但在stack_add函數中運行了太多的參數錯誤。我相信這是我做錯了。我會弄清楚。通過查看這個,我對於爲什麼將不是xml_element的節點添加回棧中有點困惑。這不會導致永無止境的循環嗎? – 2013-04-07 04:34:33

+0

再看一遍我相信你是對的,我的代碼有一個錯誤。我很抱歉。我會立即修復它。 – Josh 2013-04-08 13:59:02

2
  1. 因此,它驅動了文檔結構,但它如何導航結構?
    你發佈的是一個遞歸函數。從你的問題的性質來看,我假設你不太明白遞歸是什麼/它是如何工作的。快速谷歌搜索應該給你一些很好的信息/例子。

  2. xmlNode-> children在發現NULL時返回下一個父節點嗎?
    我假設xmlNode-> children返回一個指向包含當前節點的所有子節點的鏈表的指針。如果當前節點沒有子節點,則可能返回NULL。

  3. 這個例子非常簡單,我想了解如何讓我的代碼更好。
    我假設你寫的類是純粹迭代的。遞歸函數可以極大地簡化代碼,但性能上明智的是它們可能導致更大數據集上的問題。我肯定會推薦閱讀他們;他們可以很有趣。
+0

感謝您的答覆。是的,我的課是純粹的迭代。在我問這個問題之前,我已經做了很多關於遞歸的閱讀。也許我還是不明白,但這就是我問這個問題的原因。從我所讀到的內容來看,我收集了對使用遞歸的一般否定性,這就是爲什麼我避免使用它。 – 2013-04-05 18:38:20