2014-10-30 41 views
2

我一直在嘗試讀取一個xml文件並使用groovy的JsonBuilder將其轉換爲json。問題是,當我Caught:java.lang.StackOverflowError JsonBuilder關閉

def builder = new JsonBuilder(jsonObject) 
println builder.toPrettyString() 

打印我有一個夾縫:java.lang.StackOverflowError

這裏是整個堆棧跟蹤

Exception in thread "main" java.lang.StackOverflowError 
    at groovy.json.JsonOutput.writeObject(JsonOutput.java:259) 
    at groovy.json.JsonOutput.writeIterator(JsonOutput.java:442) 
    at groovy.json.JsonOutput.writeObject(JsonOutput.java:272) 
    at groovy.json.JsonOutput.writeIterator(JsonOutput.java:442) 
    at groovy.json.JsonOutput.writeObject(JsonOutput.java:272) 
    at groovy.json.JsonOutput.writeIterator(JsonOutput.java:442) 
    at groovy.json.JsonOutput.writeObject(JsonOutput.java:272) 
    at groovy.json.JsonOutput.writeIterator(JsonOutput.java:442) 
    at groovy.json.JsonOutput.writeObject(JsonOutput.java:272) 
    at groovy.json.JsonOutput.writeIterator(JsonOutput.java:442) 
    at groovy.json.JsonOutput.writeObject(JsonOutput.java:272) 
    at groovy.json.JsonOutput.writeIterator(JsonOutput.java:442) 
    at groovy.json.JsonOutput.writeObject(JsonOutput.java:272) 
    at groovy.json.JsonOutput.writeIterator(JsonOutput.java:442) 

下面的代碼。

package firstgroovyproject 

import groovy.json.JsonBuilder 

class XmlToJsonII { 
    static void main(def args){ 

     def carRecords = ''' 

<records> 
    <car name='HSV Maloo' make='Holden' year='2006'> 
     <countries> 
      <country> 
       Austria 
      </country> 
      <country> 
       Spain 
      </country> 
     </countries> 
     <record type='speed'>Production Pickup Truck with speed of 271kph 
     </record> 
    </car> 
    <car name='P50' make='Peel' year='1962'> 
     <countries> 
      <country> 
       Monaco 
      </country> 
     </countries> 
     <record type='size'>Smallest Street-Legal Car at 99cm wide and 59 kg 
      in weight</record> 
    </car> 
    <car name='Royale' make='Bugatti' year='1931'> 
     <record type='price'>Most Valuable Car at $15 million</record> 
     <countries> 
      <country> 
       Italia 
      </country> 
     </countries> 
    </car> 
<car name='Seat' make='Ibiza' year='1985'> 
     <record type='price'>barato</record> 
     <countries> 
      <country> 
       Spain 
      </country> 
     </countries> 
    </car> 
</records> 
    ''' 


     def xmlRecords = new XmlSlurper().parseText(carRecords) 

     def jsonObject = [:] 
     jsonObject.records = [] 
     def records = jsonObject.records 



     xmlRecords.car.each {xmlCar -> 
      records.add([ 
       countries: 
       xmlCar.countries.children().each{ country -> 
         println "country : ${country.text()}" 
         [country: country.text()] 
       }, 

       ]) 
     } 

     def builder = new JsonBuilder(jsonObject) 

     println builder.toPrettyString() 
     //println builder.toString() 
    } 
} 
+0

向我們顯示錯誤和jsonObject的整個堆棧跟蹤。最有可能在那裏有一個自我引用導致無限循環。 – cfrick 2014-10-30 23:17:03

+0

異常在線程 「主」 java.lang.StackOverflowError的 在groovy.json.JsonOutput.writeObject(JsonOutput.java:259) 在groovy.json.JsonOutput.writeIterator(JsonOutput.java:442) 在groovy.json。 JsonOutput.writeObject(JsonOutput.java:272) at groovy.json.JsonOutput.writeIterator(JsonOutput.java:442) – 2014-10-30 23:26:34

回答

3

TL; DR:你的第二(內)each應該是一個collect代替。

真實答案:返回值each是調用它的原始Iterable。在這種情況下,這將是由表達式xmlCar.countries.children()定義的XML對象集合。由於該集合中的對象將引用返回給其父母,因此您的JSON構建會導致無限的迴歸,從而導致堆棧溢出。

這不會發生在您第一次使用each時,因爲您沒有使用返回值。相反,您將添加到預先存在的列表中(records)。

通過將第二個(內部)each更改爲collect,您仍在遍歷countries元素的子代。但是,您正在編譯並返回形式爲[country:"country_string_from_xml"]的地圖列表,而不是返回原始XML子項(each的結果),這似乎是期望的行爲。

令人困惑的eachcollect是Groovy常見的菜鳥錯誤......這隻會讓上週發生在ME上的事情變得更加糟糕。 :-)