我一直在尝试读取xml文件并使用groovy的JsonBuilder将其转换为json。问题是当我用
打印时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 :(得分:4)
tl; dr:您的第二个(内部)each
应该是collect
。
真正的答案: each
的返回值是调用它的原始Iterable
。在这种情况下,它将是由表达式xmlCar.countries.children()
定义的XML对象集合。由于该集合中的对象包含对其父对象的引用,因此JSON构建会导致无限回归,从而导致堆栈溢出。
首次(外部)使用each
时不会发生这种情况,因为您没有使用返回值。相反,您要添加到预先存在的列表(records
)。
通过将第二个(内部)each
更改为collect
,您仍在迭代countries
个元素的子元素。但是,您没有返回原始XML子项(each
的结果),而是编译并返回[country:"country_string_from_xml"]
形式的映射列表,这似乎是所需的行为。
令人困惑each
和collect
是Groovy中常见的新手错误......这只会让上周发生在我身上的事情变得更加严重。 : - )