1

I’m working with Spring Batch. I have to read some complex xml-files and write them to a database. A xml-file looks like this:

<?xml version="1.0" encoding="UTF-8"?>
<KCO xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="file:///C:/DEV/schema.xsd">
    <Header/>
    <Body>
        <KC kc_id="">
            <KA ka_id="">
                <Kd kd_id="">
                    <Va va_id="">
                        <Pa pa_id=""/>
                        <Pa pa_id=""/>
                        <Pa pa_id=""/>
                    </Va>
                    <Va va_id="">
                        <Pa pa_id=""/>
                    </Va>
                </Kd>
                <Kd kd_id="">
                    <Va va_id="">
                        <Pa pa_id=""/>
                        <Pa pa_id=""/>
                        <Pa pa_id=""/>
                    </Va>
                </Kd>
            </KA>
            <KA ka_id="">
                <Kd kd_id="">
                    <Va va_id="">
                        <Pa pa_id=""/>
                        <Pa pa_id=""/>
                    </Va>
                </Kd>           
            </KA>
        </KC>
    </Body>
</KCO>

The root element is KCO. For every Pa element I have to create one output record. That record contains information’s from all parent elements (Va, Kd, KA, KC, Body and also Header). There are multiple elements from KA, Kd, Va and Pa. I tried to split the KC Element in the ItemProcessor, but that is not a good idea, right? Somewhere I read that the amount of input records and output records has to be equal. Does anybody has an idea or a pattern how I can solve this problem?

This is my code:

@Bean
@StepScope
public StaxEventItemReader<KCO> itemReader(
        @Value("#{jobParameters['InputPath']}") String inputPath) {     
    return new StaxEventItemReaderBuilder<KCO>()
            .name("itemReader")
            .resource(new FileSystemResource(inputPath))
            .addFragmentRootElements("KCO")
            .unmarshaller(primaMarshaller())
            .build();
}

@Bean
public Jaxb2Marshaller primaMarshaller() {      
    Jaxb2Marshaller pm = new Jaxb2Marshaller();
    pm.setClassesToBeBound(KCO.class);      
    return pm;      
}

@Bean
public KMPItemProcessor itemProcessor() {
    return new KMPItemProcessor();
}

@Bean
public JpaItemWriter<KonditionMP> itemWriter() {
    JpaItemWriter<KonditionMP> writer = new JpaItemWriter<KonditionMP>();
    writer.setEntityManagerFactory(emf);
    return writer;
}
TimeBandit
  • 61
  • 1
  • 9
  • `Somewhere I read that the amount of input records and output records has to be equal` That is not necessary. An input item can be transformed to multiple output items and you end up with more output records than input records. If you manage to make your item processor returns the list of records for each item, then you can use something like this: https://stackoverflow.com/questions/37866312/spring-batch-using-an-itemwriter-with-list-of-lists – Mahmoud Ben Hassine Dec 19 '19 at 13:40
  • @MahmoudBenHassine: Thanks, this tip helps me a lot. – TimeBandit Jan 16 '20 at 09:38

1 Answers1

0

The answer of my question is here: Spring Batch - Using an ItemWriter with List of Lists

Accordingly Mahmoud Ben Hassine comment.

TimeBandit
  • 61
  • 1
  • 9