2015-09-10 101 views
0

我試圖在mac上使用處理3創建生活進化的可視化表示 - 我使用XML來組織樹狀數據。下面是我如何安排我的XML代碼:XML文檔樹遍歷

<?xml version="1.0"?> 
<A> 
    <animal>Bacteria</animal> 
    <B> 
     <animal>Archea</animal> 
     <C> 
      <animal>Foraminifera</animal> 
      <D> 
       <animal>Green Algae</animal> 
       <E> 
        Mosses 
       </E> 
      </D> 
      <J> 
       <animal>Yeast</animal> 
       <animal>Sponges</animal> 
       <animal>Corals</animal> 
       <K> 
        <L>RoundWorms</L> 
        <V>SchinoDerms</V> 
       </K> 
      </J> 
     </C> 
    </B> 
</A> 

字母代表的時間分叉點,「動物」的標籤是指在特定的時間內(我要補充更多的信息,此類存在的動物作爲「時間」,但我想先解決這個問題)。

我想遍歷XML文檔,但無法弄清楚如何獲得比第一個子節點(「B」)更遠的位置。最後,我希望這看起來像是一個斷點樹,動物分別脫離它們各自的時間段(從斷點「A」開始的「細菌」分支,從斷點「B」開始的「Archea」分支等)

我想如果我能弄清楚如何通過第一個孩子,我會一切設置 - 任何想法?

+0

在以下網頁ADDNODE代碼應工作。使用樹視圖:http://stackoverflow.com/questions/28976601/recursion-parsing-xml-file-with-attributes-into-treeview-c-sharp – jdweng

回答

0

你應該開始XML reference和實例,例如LoadSaveXML下的例子>主題/ XMLYahooWeather>高級數據

你可以通過調用getChilren()它返回一個XML數組做通過您的節點基本遍歷。

XML xml; 
void setup(){ 

    xml = loadXML("data.xml"); 
    xml.trim(); 

    XML[] level0 = xml.getChildren(); 
    for(int i = 0; i < level0.length; i++){ 
    println("level0["+i+"]:" + level0[i]); 
    } 

} 

注1:在這個階段,應該在這個層面是通過從每個孩子XML實例這個數組和訪問數據的循環很簡單上面的例子可與處理3,但可能不會與舊工作版本隨着XML API的變化而變化(例如trim()函數可能會丟失)。 trim()函數應該刪除空格(新行,標籤等),否則空行可能被認爲是XML節點。總是檢查以避免意外,因爲由於XML中的空白空間。

Note2本答案中的示例假設您發佈的xml文件被保存爲data.xml文件夾,您將嘗試運行代碼。您可以隨意將其重命名爲您的XML文件實際調用的內容

好吧,現在你要經過第一級,但你如何去下一個?其實並沒有那麼糟糕。當你遍歷每個子XML節點,您可以檢查它是否hasChildren(),在這種情況下,你重複之前的操作:

  1. 打通各子XML節點的孩子XML節點

(在這個階段,這將是「盛大」的孩子:

XML xml; 

void setup(){ 
    xml = loadXML("data.xml"); 
    xml.trim(); 

    XML[] level0 = xml.getChildren(); 
    for(int i = 0; i < level0.length; i++){ 
    println("level0["+i+"]:" + level0[i]); 

    //we need to go deeper...but can we ? 
    if(level0[i].hasChildren()){ 
     XML[] level1 = level0[i].getChildren(); 

     for(int j = 0; j < level1.length; j++){ 
      println("\tlevel1["+j+"]:" + level1[j]); 
     } 

    } 
    } 

} 

您應該能夠安全地重複這一過程,以進一步深入

隨着你越來越深入,玩起來很有趣:遞歸函數。如果你不熟悉從頭開始編寫你自己的函數,你應該首先得到它的一個竅門。

他們有幾個共同點與變量:

  • 功能也都有一個類型(稱爲返回類型)
  • 功能也都有一個名字

但是做什麼主要是做一組說明。 根據這些指令的作用,它們可能返回或不返回決定函數類型的結果。

最簡單的是函數不返回任何東西(因此返回類型是void)。你之前可能使用過void setup(){},對嗎? :)

函數創建一個單獨的作用域(在{}符號內),因此只有在該函數範圍內定義的變量纔可見,除非結尾返回結果變量。

函數可以有0個或多個參數/參數(請參閱它們的選項)。 例如setup()不需要參數,但point()需要兩個(x和y)。

遞歸函數本質上只是一個調用自身的函數(通常使用不同的參數)。

在XML的情況下,你可以使用一個遞歸函數通過各級向下鑽取:

XML xml; 

void setup(){ 

    xml = loadXML("data.xml"); 
    xml.trim(); 

    recursiveTraverse(xml); 
} 

void recursiveTraverse(XML xml){ 
    XML[] childNodes = xml.getChildren(); 
    for(int i = 0; i < childNodes.length; i++){ 
    println(childNodes[i].getName()+":"+childNodes[i].toString()); 
    if(childNodes[i].hasChildren()){ 
     recursiveTraverse(childNodes[i]); 
    } 
    } 
} 
+0

工作得非常好!非常感謝你對遞歸函數的這種詳細迴應,你剛剛震撼了我的世界! :d –