Groovy实现深层XML结构转无表头CSV的脚本求助
Groovy实现深层XML结构转无表头CSV的脚本求助
我来帮你搞定这个Groovy脚本的问题!你想要的效果是:每个<stock>节点先输出它的field1和field2拼接的行,紧接着输出该节点下所有<positions>的data1和data2拼接的行,最终生成无表头的CSV对吧?
先确认下你提供的XML结构(注意:原始XML缺少根节点,Groovy解析时会报错,建议补充根节点比如<root>):
<root> <stock> <field1>Header</field1> <field2>H1</field2> <positions> <data1>Hello</data1> <data2>P1</data2> </positions> <positions> <data1>World</data1> <data2>P2</data2> </positions> </stock> <stock> <field1>Header</field1> <field2>H2</field2> <positions> <data1>Hello</data1> <data2>P3</data2> </positions> <positions> <data1>World</data1> <data2>P4</data2> </positions> </stock> </root>
你期望的CSV输出是:
Header|H1 Hello|P1 World|P2 Header|H2 Hello|P3 World|P4
你原来的脚本问题在于只处理了<positions>节点,没有把每个<stock>自身的field1和field2行加进去,而且重复使用了XmlParser和XmlSlurper,其实用一个就足够了。
下面是修正后的完整脚本:
// 假设ins是你的原始XML输入字符串 def xmlContent = "<root>${ins}</root>" // 给无根节点的XML补充根节点 def parsedXml = new XmlSlurper().parseText(xmlContent) // 用列表收集所有CSV行 def csvLines = [] // 遍历每个stock节点 parsedXml.stock.each { stock -> // 先添加当前stock的字段行 def stockLine = "${stock.field1.text()}|${stock.field2.text()}" csvLines.add(stockLine) // 再遍历当前stock下的所有positions节点,添加对应行 stock.positions.each { position -> def posLine = "${position.data1.text()}|${position.data2.text()}" csvLines.add(posLine) } } // 把所有行用换行符连接成最终CSV内容 def finalCsv = csvLines.join("\n") // 输出结果,也可以写入文件或做其他处理 println finalCsv
这个脚本的逻辑很清晰:
- 用
XmlSlurper解析XML(它比XmlParser更适合这种遍历场景) - 遍历每个
<stock>,先把该stock的两个字段拼接成一行加入列表 - 再遍历该stock下的所有
<positions>,每个positions的两个字段拼接成一行加入列表 - 最后把列表里的所有行用换行符连接,就得到了你想要的CSV内容
如果你的原始XML本身已经有根节点,去掉xmlContent那行的根节点包裹即可。运行这个脚本就能得到你期望的输出啦!
备注:内容来源于stack exchange,提问作者Smn
相关产品推荐
相关产品推荐

