0
votes

Hi I have a spring batch job to read from xml file and write to Csv file , I have an issue to change this working example works with xml file with a nested tag :

in the working example xml is :

<?xml version="1.0" encoding="UTF-8" ?>
<company>
    <record >
        <name>ben</name>
        <age>31</age>
        <dob>31/8/1982</dob>
        <income>200,000</income>
    </record>
    <record >
        <name>aya</name>
        <age>30</age>
        <dob>26/7/1983</dob>
        <income>100,999</income>
    </record>
   </company>

I want it to work with xml file like this :

<company>
    <record >
        <name>ben</name>
        <age>31</age>
        <dob>31/8/1982</dob>
        **<income>
           <Gross> 2000<Gross/>
           <Net>1000</Net>
        </income>**
    </record>
    <record >
        <name>aya</name>
        <age>30</age>
        <dob>26/7/1983</dob>
        <income>100,999</income>
    </record>
   </company>

  <batch:job id="reportJob">
    <batch:step id="step1">
    <batch:tasklet>
        <batch:chunk reader="xmlItemReader" 
            writer="cvsFileItemWriter" processor="filterReportProcessor"
            commit-interval="1">
        </batch:chunk>
    </batch:tasklet>
    </batch:step>
  </batch:job>

  <!-- Filtering process -->
  <bean id="filterReportProcessor" class="com.mkyong.processor.FilterReportProcessor" />

  <bean id="xmlItemReader" 
        class="org.springframework.batch.item.xml.StaxEventItemReader">
    <property name="fragmentRootElementName" value="record" />
    <property name="resource" value="classpath:xml/report.xml" />
    <property name="unmarshaller" ref="reportUnmarshaller" />
  </bean>

  <!-- Read and map values to object, via jaxb2 -->
  <bean id="reportUnmarshaller" class="org.springframework.oxm.jaxb.Jaxb2Marshaller">
    <property name="classesToBeBound">
    <list>
        <value>com.ben.model.Report</value>
    </list>
    </property>
  </bean>

  <bean id="cvsFileItemWriter" class="org.springframework.batch.item.file.FlatFileItemWriter">
    <!-- write to this csv file -->
    <property name="resource" value="file:cvs/report.csv" />
    <property name="shouldDeleteIfExists" value="true" />

    <property name="lineAggregator">
      <bean
        class="org.springframework.batch.item.file.transform.DelimitedLineAggregator">
        <property name="delimiter" value="," />
        <property name="fieldExtractor">
          <bean
            class="org.springframework.batch.item.file.transform.BeanWrapperFieldExtractor">
            <property name="names" value="refId, name, age, csvDob, income" />
           </bean>
        </property>
       </bean>
    </property>
  </bean>

</beans>

the POJO is like this :

@XmlRootElement(name = "record")
public class Report {

    private int refId;
    private String name;
    private int age;
    private Date dob;
    private BigDecimal income;

    @XmlAttribute(name = "refId")
    public int getRefId() {
        return refId;
    }

    public void setRefId(int refId) {
        this.refId = refId;
    }

    @XmlElement(name = "age")
    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    @XmlElement
    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @XmlJavaTypeAdapter(JaxbDateAdapter.class)
    @XmlElement
    public Date getDob() {
        return dob;
    }

    @XmlJavaTypeAdapter(JaxbDateAdapter.class)
    public void setDob(Date dob) {
        this.dob = dob;
    }

    @XmlJavaTypeAdapter(JaxbBigDecimalAdapter.class)
    @XmlElement
    public BigDecimal getIncome() {
        return income;
    }

    public void setIncome(BigDecimal income) {
        this.income = income;
    }

    // for csv demo only
    public String getCsvDob() {

        SimpleDateFormat dateFormat = new SimpleDateFormat("dd/MM/yyyy");
        return dateFormat.format(getDob());

    }

}

so far I tried to create a class Income in the record and added Gross and Net in the XML config file like this : <property name="names" value="refId, name, age, csvDob, Gross,Net" />,but that didn t work , I didn t got the values of Gross and Net . what I should do to get it working please.

1

1 Answers

0
votes

This is more a JAXB question rather than Spring Batch question. Your issue is how to map this XML snippet:

<record >
    <name>ben</name>
    <age>31</age>
    <dob>31/8/1982</dob>
    <income>
       <Gross> 2000<Gross/>
       <Net>1000</Net>
    </income>
</record>

to your domain object of type Report. As defined in your example, the mapping does not work because the field income is of type BigDecimal.

so far I tried to create a class Income

You need to update the income field type from BigDecimal to Income.