2012-04-12 50 views
1

Groovy有一點xml解析問題。
這是,我的數據是什麼樣子:Groovy:創建一個新的xml結構以及如何在構建時插入新節點

ID  001=1234 
sID  001=q8b6v 
d1  001=some Text 
d2  001=more Text2 
tzh  001=data 
dse  001=data 
ID  001=567823 
sID  001=l3n37v2 
d1  001=some Text 
d2  001=more Text2 
hrg  001=data 
dfe  001=data 
... 

我需要的ID,SID和D1。

我得到什麼:

What I get: 
<add> 
    <doc> 
    <field name='ID'>00573419</field> 
    <field name='sID'>20120110572</field> 
    <field name='d1'>some Text</field> 
    <field name='ID'>00573406</field> 
    <field name='sID'>20120111110</field> 
    <field name='d1'>some Text2</field> 
    </doc> 
</add> 

我想要什麼:

<add> 
    <doc> 
    <field name='ID'>00573419</field> 
    <field name='sID'>20120110572</field> 
    <field name='d1'>some Text</field> 
    </doc> 
    <doc> 
    <field name='ID'>00573406</field> 
    <field name='sID'>20120111110</field> 
    <field name='d1'>some Text2</field> 
    </doc> 
</add> 

這是我的代碼部分:

if(!dataFile.exists()){ 
     println "File does not exist!" 
    }else{ 

     def key1, key2, key3, key4 
     def val1, val2, val3, val4 

     xml.add{ 
      doc { 
       dataFile.eachLine {line -> 
        if(line.startsWith(regExId)){ 
         (key1, val1) = line.split(/001=/).collect {it.trim()} 
         field(name:key1, val1) 
        } 
        if(line.startsWith(regExEntryId)){ 
         (key2, val2) = line.split(/001=/).collect {it.trim()} 
         field(name:key2, val2) 
        } 
        if(line.startsWith(regExTitle)){ 
         (key3, val3) = line.split(/001=/).collect {it.trim()} 
         field(name:key3, val3) 
        } 
       } 
      } 
     } 

我想保持儘可能簡單。所以我需要的是'如果這裏開始一個新的regExId然後開始一個新的xml-block',這樣我可以根據需要輕鬆地添加新的數據部分(如d2)。沒有現有的xml文件。
感謝您的任何信息!

+0

您的數據''
在每一行的結束? – 2012-04-12 14:12:27

+0

我現在看到了......不,它在每行的末尾沒有
? – Dave 2012-04-12 14:15:02

+0

編輯該部分,謝謝。現在應該是正確的。 – Dave 2012-04-12 14:16:27

回答

1

這是我想出了:

import groovy.xml.MarkupBuilder 

dataFile = new File('data.txt') 

// A closure that will add a new doc element to our xml 
def addDoc = { builder, data -> 
    builder.doc { 
    data.each { k, v -> 
     builder.field(name:k, v) 
    } 
    } 
} 


String result = new StringWriter().with { out -> // create a StringWriter 
    new MarkupBuilder(out).with { xml ->   // pass it to MarkupBuilder 
    add {          // create our root level element 
     def data = [:] 
     // Then, for each line in our input file 
     dataFile.eachLine { line -> 
     // Get the key and value as you had it 
     def (key,value) = line.split(/001=/)*.trim() 
     // Just use the keys we want 
     if(key in [ 'ID', 'sID', 'd1' ]) { 
      // If we have a new ID and we have data 
      if(key == 'ID' && data) { 
      // Add it to the document 
      addDoc(xml, data) 
      // And start again with a new map 
      data = [ ID: value ] 
      } 
      else { 
      // Otherwise, just add the key to the map 
      data[ key ] = value 
      } 
     } 
     } 
     // So, we've run out of lines. If we have data, write it in 
     if(data) addDoc(xml, data) 
    } 
    } 
    // Convert our StringWriter to a String (this goes into the variable `result) 
    out.toString() 
} 
// And print it out 
println result 
+0

只是「哇」!謝謝!我有很多東西要學習:)結果是正確的。只有一個問題:'data = [ID:value]'ID從哪裏來? – Dave 2012-04-12 15:12:48

+0

@ user1095901這是新地圖條目的關鍵(因爲我們知道它是'ID')......可能會把'data = [(key):value]'混淆不清。這基本上是把新的ID放入地圖中,以便下次寫入文檔 – 2012-04-12 15:18:31

+0

謝謝您的快速響應。我會將我的問題標記爲已解決。再次感謝你。 – Dave 2012-04-12 15:23:21