в рекурсии, чтобы увидеть, что это такое.

я есть образец XML-файла LEDEShttps://codebeautify.org/xmlviewer/cbdc79e7

Генерируемый класс Ledesxmlebilling21 с использованием JDKxjc как показано ниже и схема Ledes21.xsdhttps://codebeautify.org/xmlviewer/cb974a2e

xjc -d src ledes21.xsd

И я преобразую XML в объект Java, используя JAX-B, как показано ниже

Ledesxmlebilling21 XMLtoObject(InputStream fis) throws Exception {
    JAXBContext context = JAXBContext.newInstance(Ledesxmlebilling21.class)
    Unmarshaller um = context.createUnmarshaller()
    Ledesxmlebilling21 ledes = (Ledesxmlebilling21) um.unmarshal(fis)
    return ledes
}

И я пытаюсь создать карту с объектами InvoiceinvId Значение атрибута как Ключ, а Значения как список всех вложенных атрибутов объекта 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)
}

Я получаю ниже исключения с фактическимLedesxmlebilling21 объект

Disconnected from the target VM, address: '127.0.0.1:59759', transport: 'socket'
2017-12-11 11:04:06 - Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Handler dispatch failed; nested exception is java.lang.StackOverflowError] with root cause
java.lang.StackOverflowError: null
    at org.codehaus.groovy.util.AbstractConcurrentMap.getOrPut(AbstractConcurrentMap.java:37)
    at org.codehaus.groovy.reflection.GroovyClassValuePreJava7.get(GroovyClassValuePreJava7.java:94)
    at org.codehaus.groovy.reflection.ClassInfo.getClassInfo(ClassInfo.java:143)
    at org.codehaus.groovy.runtime.metaclass.MetaClassRegistryImpl.getMetaClass(MetaClassRegistryImpl.java:265)
    at org.codehaus.groovy.runtime.InvokerHelper.getMetaClass(InvokerHelper.java:879)
    at org.codehaus.groovy.runtime.callsite.AbstractCallSite.createPojoMetaClassGetPropertySite(AbstractCallSite.java:351)
    at org.codehaus.groovy.runtime.callsite.AbstractCallSite.createGetPropertySite(AbstractCallSite.java:327)
    at org.codehaus.groovy.runtime.callsite.GetEffectivePojoPropertySite.acceptGetProperty(GetEffectivePojoPropertySite.java:56)
    at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callGetProperty(AbstractCallSite.java:296)
    at com.validation.rule.processor.impl.LedesXmlRuleProcessor.extractFileItemNbr(LedesXmlRuleProcessor.groovy:82)
    at sun.reflect.GeneratedMethodAccessor82.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:93)
    at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:325)
    at org.codehaus.groovy.runtime.metaclass.ClosureMetaClass.invokeMethod(ClosureMetaClass.java:384)
    at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1027)
    at org.codehaus.groovy.runtime.callsite.PogoMetaClassSite.callCurrent(PogoMetaClassSite.java:69)
    at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callCurrent(AbstractCallSite.java:174)
    at com.validation.rule.processor.impl.LedesXmlRuleProcessor$_extractFileItemNbr_closure2.doCall(LedesXmlRuleProcessor.groovy:87)
 RanPaul08 дек. 2017 г., 16:55
обновил вопрос, это довольно сложный объект с вложенными объектами, я сгенерировал классы используяxjc команда
 aristotll08 дек. 2017 г., 16:41
Можете ли вы показать свое определениеLedesxmlebilling21? У разных людей могут быть разные условные обозначения.

Ответы на вопрос(2)

рекурсивно перебирать отличные свойства.

Я пропускаю разбор 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;
    }

}

Выход:

[Invoice 31:[12, 13, 11, 10], Invoice 32:[52, 53, 51, 50]]
Обновить:

В случае циклов, не просто обойтиList<Integer> extracted извлеченных целых, а также набор посещенных входов, и в каждом методе извлечения проверьте, есть ли данный вход уже в списке.

 tkruse12 дек. 2017 г., 01:47
Stackoverflow означает, что существует цикл, скорее всего, какой-то экземпляр имеет себя как свойство. Не должно быть слишком сложно для отладки. Добавитьprintln(" $prop : $val") в рекурсии, чтобы увидеть, что это такое.
 RanPaul11 дек. 2017 г., 18:13
я получаюjava.lang.StackOverflowError: null исключение с фактическимLedesxmlebilling21 объект, я обновил вопрос с вашим решением и добавил номера строк в код, вы можете проверить?

что схема будет иметь циклическое свойство. Посмотрите здесь, возможно:JAXB Отображение циклических ссылок на XML

Ваш ответ на вопрос