2013-02-28 20 views
1

給出地圖ID和路徑,對於給定的節點,我建立一個XML樹:XML樹建設者常規

def trees = [:] 
trees.put(1,"TEST/folder1") 
trees.put(2,"TEST/folder2") 
trees.put(3,"TEST/folder1/folder1.1") 
trees.put(4,"TEST/folder2/folder2.1/folder2.1.2") 
trees.put(5,"TEST/folder1/folder1.2") 
trees.put(6,"TEST/folder1/folder1.2/folder1.2.1/")       
trees.put(7,"TEST/folder1/folder1.2/folder1.2.2/") 
trees.put(8,"TEST/folder1/folder1.2/folder1.2.2/1.2.2.1")  


sw = new StringWriter() 

def rslt = { [:].withDefault{ owner.call() } }().with { t -> 
    trees.each { k, v -> 
     v.tokenize('/').inject(t) { tr, i -> tr[ i ] } 
    } 
    return t 
} 

new groovy.xml.MarkupBuilder(sw).with { 
      visitor = { k, v -> "$k" { v instanceof Map ? v.collect(visitor) : mkp.yield(v) } } 
      ROOT { rslt.collect visitor } 
     } 
println sw.toString()  

最後得到如下的輸出:

<TEST> 
    <folder1> 
     <folder1.1 /> 
     <folder1.2> 
     <folder1.2.1 /> 
     <folder1.2.2> 
      <1.2.2.1 /> 
     </folder1.2.2> 
     </folder1.2> 
    </folder1> 
    <folder2> 
     <folder2.1> 
     <folder2.1.2 /> 
     </folder2.1> 
    </folder2> 
    </TEST> 
</ROOT> 

是有一個Groovy添加屬性id,名稱,父深度,url,從初始樹形圖值

形成的阱XML文檔的實施例:

<folder2 name="folder2" id="2" parent="TEST" depth="1" url="TEST/folder2"> 
     <folder2.1.1 name="folder2.1.1" id="2" parent="TEST" depth="2" url="TEST/folder2"> 
      <folder2.1.1.1 name="folder2.1.1.1" id="3" parent="TEST" depth="3" url="TEST/folder2"/> 
     </folder2.1.1> 
</folder2> 

任何意見或建議?

乾杯

+0

你有模特課嗎? – Will 2013-02-28 11:52:25

+0

模型類是一個域,具有存儲在其中的字符串路徑和標識 – 2013-02-28 14:58:06

回答

0

我會開始假設你的模型,並創造了一些模擬數據:

class Dir { 
    String name, url, id 
    Dir parent 
    List<Dir> children 

    String toString() { "Dir(name:$name, url:$url, parent:$parent)" } 
} 

dir1 = new Dir(name: "folder1", url: "TEST/folder1", id: "1") 
dir2 = new Dir(name: "folder2", url: "TEST/folder2", id: "2") 
dir11 = new Dir(name: "folder1.1", url: "TEST/folder1/folder1.1", id: "11", parent: dir1) 
dir12 = new Dir(name: "folder1.2", url: "TEST/folder1/folder1.2", id: "12", parent: dir1) 
dir121 = new Dir(name: "folder1.2.1", url: "TEST/folder1/folder1.2/folder1.2.1", id: "121", parent: dir12) 
dir212 = new Dir(name: "folder2.1.2", url:"TEST/folder2/folder2.1/folder2.1.2", id: "212", parent: dir2) 

dir1.children = [dir11, dir12] 
dir12.children = [dir121] 
dir2.children = [dir212] 

dirs = [dir1, dir2] 

現在你只使用MarkupBuilder的或streamingmarkupbuilder構建XML結構,使用GString的創建動態標籤:

sw = new StringWriter() 

def depthCalculator // used to calculate the depth of the folder object 
depthCalculator = { Dir dir, Integer count = 1 -> 
    if (dir.parent) depthCalculator dir.parent, count++ 
    count 
} 

new groovy.xml.MarkupBuilder(sw).with { 

    setDoubleQuotes true 

    /* 
    * This closure creates the tag using a gstring for the tag name. 
    * It recursively iterates through every children of the Dir parent object. 
    */ 
    def collector 
    collector = { Dir dir -> 
    def depth = depthCalculator dir 
    "${dir.name}" (
      name: dir.name, 
      id: dir.id, 
      url: dir.url, 
      parent: (dir.parent?.name ?: ""), 
      depth: depth) { 
     dir.children.each collector 
    } 
    } 

    dirs.each collector 
} 

println sw.toString() 

這是生成的XML:

<folder1 name="folder1" id="1" url="TEST/folder1" parent="" depth="1"> 
    <folder1.1 name="folder1.1" id="11" url="TEST/folder1/folder1.1" parent="folder1" depth="2" /> 
    <folder1.2 name="folder1.2" id="12" url="TEST/folder1/folder1.2" parent="folder1" depth="2"> 
    <folder1.2.1 name="folder1.2.1" id="121" url="TEST/folder1/folder1.2/folder1.2.1" parent="folder1.2" depth="2" /> 
    </folder1.2> 
</folder1> 
<folder2 name="folder2" id="2" url="TEST/folder2" parent="" depth="1"> 
    <folder2.1.2 name="folder2.1.2" id="212" url="TEST/folder2/folder2.1/folder2.1.2" parent="folder2" depth="2" /> 
</folder2> 
+0

Thanks Will,groovy中有趣的遞歸內容。無論如何,我的目標是保持收集所有子元素的rslt閉包,以便我可以解析它們並使用或與收集器示例結合使用。 – 2013-03-01 20:06:26