Java Groovy:使用JAX-B对象创建映射&x27;特殊属性
我有一个示例LEDES XML文件 使用JDK的Java Groovy:使用JAX-B对象创建映射&x27;特殊属性,java,xml,groovy,Java,Xml,Groovy,我有一个示例LEDES XML文件 使用JDK的xjc生成Ledesxmlebilling21类,如下所示和Ledes21.xsd模式 我使用JAX-B将XML转换为Java对象,如下所示 Ledesxmlebilling21 XMLtoObject(InputStream fis) throws Exception { JAXBContext context = JAXBContext.newInstance(Ledesxmlebilling21.class) Unmarsha
xjc
生成Ledesxmlebilling21类,如下所示和Ledes21.xsd模式
我使用JAX-B将XML转换为Java对象,如下所示
Ledesxmlebilling21 XMLtoObject(InputStream fis) throws Exception {
JAXBContext context = JAXBContext.newInstance(Ledesxmlebilling21.class)
Unmarshaller um = context.createUnmarshaller()
Ledesxmlebilling21 ledes = (Ledesxmlebilling21) um.unmarshal(fis)
return ledes
}
['Invoice 31' : [10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33]
'Invoice 32' : [50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73]
]
我正在尝试创建一个映射,其中Invoice对象的invId
属性值作为键,值作为Invoice对象的所有嵌套属性的fileItemNbr
值的列表,如下所示
['Invoice 31' : [10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33]
'Invoice 32' : [50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73]
]
有人能帮我吗
使用解决方案更新
def extractFileItemNbr(input, List<Integer> extracted) {
input.properties.each { prop, val -> //LedesXmlRuleProcessor.groovy:82)
if (prop in ["metaClass", "class"]) return
if (prop == 'file_item_nbr') {
extracted << val
} else {
extractFileItemNbr(val, extracted) //LedesXmlRuleProcessor.groovy:87)
}
}
}
def extractFileItemNbr(List input, List<Integer> extracted) {
input.each {
extractFileItemNbr(it, extracted)
}
}
void testExtract(Ledesxmlebilling21 ledesxmlebilling21) {
def xmlInvoices = ledesxmlebilling21.firm.client.invoice.flatten()
Map<String, List<Integer>> extracted = [:]
println "invoices -- "+xmlInvoices
for (Invoice invoice : xmlInvoices) {
def accuList = []
extractFileItemNbr(invoice, accuList)
extracted.put(invoice.invId, accuList)
}
println("extracted file_item_nbr "+ extracted)
}
我相信你想要的是 我跳过JAX-B解析,因为您已经解决了这个问题,并使用我自己的类。groovy代码不是惯用的,可以缩短
class LedesStatementTest extends GroovyTestCase {
// Recursive function adding file_item_nbr to given list
def extractFileItemNbr(input, List<Integer> extracted) {
input.properties.each { prop, val ->
if (prop in ["metaClass", "class"]) return
if (prop == 'file_item_nbr') {
// println(" $prop : $val")
extracted << val
} else {
extractFileItemNbr(val, extracted)
}
}
}
// deal with list fields
def extractFileItemNbr(List input, List<Integer> extracted) {
input.each {
extractFileItemNbr(it, extracted)
}
}
void testExtract() {
List<LedesInvoice> invoices = [new LedesInvoice([inv_id: 'Invoice 31',
file_item_nbr: 10,
statement: new LedesStatement([file_item_nbr: 11]),
summary: [new LedesTaxSummary([file_item_nbr: 12]), new LedesTaxSummary([file_item_nbr: 13])]]),
new LedesInvoice([inv_id: 'Invoice 32',
file_item_nbr: 50,
statement: new LedesStatement([file_item_nbr: 51]),
summary: [new LedesTaxSummary([file_item_nbr: 52]),
new LedesTaxSummary([file_item_nbr: 53])]])
]
Map<String, List<Integer>> extracted = [:]
for (LedesInvoice invoice : invoices) {
def accuList = []
extractFileItemNbr(invoice, accuList)
extracted.put(invoice.inv_id, accuList)
}
println(extracted)
}
// data classes, similar to Ledes XML, simplified
static class LedesInvoice {
String inv_id;
int file_item_nbr;
LedesStatement statement;
List<LedesTaxSummary> summary;
}
static class LedesStatement {
int file_item_nbr;
}
static class LedesTaxSummary {
int file_item_nbr;
}
}
更新:
在循环的情况下,不要只传递一个提取的int的
列表,还要传递一组访问的输入,并在每个提取方法中检查给定的输入是否已经在列表中。我猜模式将具有循环属性。看看这里,也许是:你能给出你对ledesxmlebiling21
的定义吗?不同的人可能有不同的名称约定。更新了这个问题,这是一个非常复杂的对象和嵌套对象,我使用xjc
commandam getjava.lang.StackOverflowerr:null
与实际的Ledesxmlebilling21
对象异常生成了这些类,我已经用你的解决方案更新了这个问题,并在代码中添加了行号,你能检查一下吗?Stackoverflow意味着有一个循环,很可能某个实例本身就是一个属性。调试应该不会太困难。在递归中添加一个println(“$prop:$val”)
,查看它是哪个。
class LedesStatementTest extends GroovyTestCase {
// Recursive function adding file_item_nbr to given list
def extractFileItemNbr(input, List<Integer> extracted) {
input.properties.each { prop, val ->
if (prop in ["metaClass", "class"]) return
if (prop == 'file_item_nbr') {
// println(" $prop : $val")
extracted << val
} else {
extractFileItemNbr(val, extracted)
}
}
}
// deal with list fields
def extractFileItemNbr(List input, List<Integer> extracted) {
input.each {
extractFileItemNbr(it, extracted)
}
}
void testExtract() {
List<LedesInvoice> invoices = [new LedesInvoice([inv_id: 'Invoice 31',
file_item_nbr: 10,
statement: new LedesStatement([file_item_nbr: 11]),
summary: [new LedesTaxSummary([file_item_nbr: 12]), new LedesTaxSummary([file_item_nbr: 13])]]),
new LedesInvoice([inv_id: 'Invoice 32',
file_item_nbr: 50,
statement: new LedesStatement([file_item_nbr: 51]),
summary: [new LedesTaxSummary([file_item_nbr: 52]),
new LedesTaxSummary([file_item_nbr: 53])]])
]
Map<String, List<Integer>> extracted = [:]
for (LedesInvoice invoice : invoices) {
def accuList = []
extractFileItemNbr(invoice, accuList)
extracted.put(invoice.inv_id, accuList)
}
println(extracted)
}
// data classes, similar to Ledes XML, simplified
static class LedesInvoice {
String inv_id;
int file_item_nbr;
LedesStatement statement;
List<LedesTaxSummary> summary;
}
static class LedesStatement {
int file_item_nbr;
}
static class LedesTaxSummary {
int file_item_nbr;
}
}
[Invoice 31:[12, 13, 11, 10], Invoice 32:[52, 53, 51, 50]]