如何在Groovy中按条件实现findAll/集合解析XML生成指定JSON
解决Groovy中带条件解析XML生成指定JSON的问题
你的问题核心在于没有针对E1EDP19节点的QUALF值做精准筛选,直接取所有节点的文本会导致结果不符合预期。我们可以利用Groovy集合的find方法,针对每个E1EDP01节点分别定位符合条件的子节点,再提取对应字段。
以下是修正后的完整代码:
import groovy.xml.XmlSlurper import groovy.json.JsonBuilder class ParsingXML { static main(args) { def xml = new XmlSlurper().parseText('''<?xml version="1.0" encoding="UTF-8"?> <INVOIC02> <IDOC> <E1EDP01> <POSEX>000010</POSEX> <MENGE>0</MENGE> <GEWEI>GRM</GEWEI> <PSTYV>ZTAN</PSTYV> <WERKS>1528</WERKS> <E1EDP19> <QUALF>002</QUALF> <IDTNR>000000000010120368</IDTNR> <KTEXT>Rocephin Vial 1g</KTEXT> </E1EDP19> <E1EDP19> <QUALF>003</QUALF> <IDTNR>07640149612004</IDTNR> </E1EDP19> </E1EDP01> <E1EDP01> <E1EDP19> <QUALF>010</QUALF> <IDTNR>OBD-2</IDTNR> </E1EDP19> <E1EDP19> <QUALF>002</QUALF> <IDTNR>000000000010120368</IDTNR> <KTEXT>Rocephin Vial 1g</KTEXT> </E1EDP19> <E1EDP19> <QUALF>003</QUALF> <IDTNR>07640149612004</IDTNR> </E1EDP19> </E1EDP01> </IDOC> </INVOIC02> ''') def builder = new JsonBuilder() builder { commonInvoiceInput { itemInfo xml.IDOC.E1EDP01.collect { item -> // 找到QUALF=002的E1EDP19节点 def itemNode = item.E1EDP19.find { it.QUALF.text() == '002' } // 找到QUALF=010的E1EDP19节点 def batchNode = item.E1EDP19.find { it.QUALF.text() == '010' } [ itemCode: itemNode?.IDTNR.text() ?: '', itemName: itemNode?.KTEXT.text() ?: '', lineNumber: item.POSEX.text() ?: '', selection: '', bathNo: batchNode?.IDTNR.text() ?: '', unitCode: '', unitName: item.ZE1EDP01?.MENEE.text() ?: '', // 原XML无此节点,默认留空 unitPrice: item.E1DP05?.KRATE.text() ?: '', // 原XML无此节点,默认留空 quantity: item.MENGE.text() ?: '', itemTotalAmountWithoutTax: '', TaxPercentage: '' ] } } } println(builder.toPrettyString()) } }
关键代码解释:
- 使用
item.E1EDP19.find { it.QUALF.text() == '002' }精准定位当前E1EDP01节点下符合条件的子节点,避免取到所有E1EDP19的文本拼接值。 - 用
?.安全导航运算符和?:Elvis运算符处理节点不存在的情况,既防止空指针异常,又能让字段默认显示为空字符串。 - 原XML中不存在
ZE1EDP01和E1DP05节点,代码会自动将对应字段设为空,完美匹配你的期望输出。
运行结果:
执行代码后会生成你想要的JSON结构:
{ "commonInvoiceInput": { "itemInfo": [ { "itemCode": "000000000010120368", "itemName": "Rocephin Vial 1g", "lineNumber": "000010", "selection": "", "bathNo": "", "unitCode": "", "unitName": "", "unitPrice": "", "quantity": "0", "itemTotalAmountWithoutTax": "", "TaxPercentage": "" }, { "itemCode": "000000000010120368", "itemName": "Rocephin Vial 1g", "lineNumber": "", "selection": "", "bathNo": "OBD-2", "unitCode": "", "unitName": "", "unitPrice": "", "quantity": "", "itemTotalAmountWithoutTax": "", "TaxPercentage": "" } ] } }
内容的提问来源于stack exchange,提问作者Developer XSLT
相关产品推荐
相关产品推荐

