Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/348.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/xml/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java Groovy:使用JAX-B对象创建映射&x27;特殊属性_Java_Xml_Groovy - Fatal编程技术网

Java Groovy:使用JAX-B对象创建映射&x27;特殊属性

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

我有一个示例LEDES XML文件

使用JDK的
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 get
java.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]]