'Creating a JAVA Object from XML using Jackson XML for multiple elements with same TAG

I have the following XML Structure which I am using to create a Java Object.

<TABLE NAME="AB" ID="10" CODE="ABC123" RANK="102" YEAR="2022"
       TIMESTAMP="2021-05-11-16.19.44.572000">
    <TABLE NAME="CD">
        <ROW CODE="BCD456" SERIAL="A" ORDER="1" DESCRIPTION_1="TEST1"
             DESCRIPTION_2="TEST2 19" DESCRIPTION_3="TEST 3" STATUS_CODE="496" STATUS_INDICATOR="J"
             PRODUCT_NAME="SHIP ">
            <TABLE NAME="CD1">
                <ROW CD1_CODE=" 11N" CD1_DESCRIPTION="T"/>
                <ROW CD1_CODE=" 2KA" CD1_DESCRIPTION="T"/>
            </TABLE>
            <TABLE NAME="CD2">
                <ROW CD2_CODE="11" CD2_DESCRIPTION="----"/>
                <ROW CD2_CODE="12" CD2_DESCRIPTION="----"/>
                <ROW CD2_CODE="35" CD2_DESCRIPTION="----"/>
            </TABLE>
            <TABLE NAME="CD3"/>
        </ROW>
    </TABLE>
    <TABLE NAME="EF" CODE="EFG789">
        <ROW FILE="1" FILE_NAME="TEST.pdf" TIMESTAMP="2021-06-22T08:32:08.055854">
            <FILE_DATA>TESTDATA</FILE_DATA>
        </ROW>
    </TABLE>
</TABLE>

I have created an XMLMapper such as below which retrieves the values from the Java Object. The main issue for me is when I have multiple <TABLE> element in the XML under the same Parent element.

In this first scenario, the <TABLE NAME="AB"> has two child TABLES <TABLE NAME="CD"> and <TABLE NAME="EF">.

In this second scenario, the <TABLE NAME="CD"> has three child TABLES <TABLE NAME="CD1">, <TABLE NAME="CD2"> and <TABLE NAME="CD3"> with subsequent <ROW> of data.

I am trying to use the XMLMapper code provided below along with the neccesary Java Classes to store the relevant data from the XML. I am able to validate the data being stored in the mapper for <TABLE NAME = "CD1"> and it's child elements <ROW>

I have tried the answers suggested in this post, but it doesn't exactly work for my scenario.

Now, I am trying to retrieve and store the elements from <TABLE NAME = "CD2"> and ```. This is where I am getting an error stating

Multiple fields representing property "TABLE": createcsv.elements.CDRow#cd1Table vs createcsv.elements.CDRow#cd2Table

XMLMapperApp.java

public class XmlMapperApp {

    public static void main(String[] args) {
        try {
            File xmlFile = new File("./resource/test.xml").getAbsoluteFile();
            XmlMapper xmlMapper = new XmlMapper();
            xmlMapper.disable(DeserializationFeature.FAIL_ON_IGNORED_PROPERTIES);
            EmployeeXML employeeXML = xmlMapper.readValue(xmlFile, EmployeeXML.class);
        } catch (Exception ex) {
            System.out.println(ex.getMessage());
        }
    }
}

EmployeeXML.java

@AllArgsConstructor
@NoArgsConstructor
@JacksonXmlRootElement(localName = "TABLE")
public class EmployeeXML {

    @JacksonXmlProperty(isAttribute = true, localName = "NAME")
    private String name;

    @JacksonXmlProperty(isAttribute = true, localName =  "ID")
    private String id;

    @JacksonXmlProperty(isAttribute = true, localName = "CODE")
    private String code;

    @JacksonXmlProperty(isAttribute = true, localName = "RANK")
    private String rank;

    @JacksonXmlProperty(isAttribute = true, localName = "YEAR")
    private String year;
    @JacksonXmlProperty(isAttribute = true, localName =  "TIMESTAMP")
    private String timestamp;

    @JacksonXmlProperty(localName = "TABLE")
    private CDTable cdTable;

    @JacksonXmlProperty(localName = "TABLE")
    private EFTable efTable;
}

RowElement.java

public interface RowElement {
}

CDTable.java

@NoArgsConstructor
@AllArgsConstructor
@JacksonXmlRootElement(localName = "TABLE")
public class CDTable {
    @JacksonXmlProperty(isAttribute = true, localName = "NAME")
    private String name;

    @JacksonXmlProperty(localName = "ROW")
    private CDRow cdRow;
}

CDRow.java

@NoArgsConstructor
@AllArgsConstructor
@JacksonXmlRootElement(localName = "ROW")
public class CDRow implements RowElement {

    @JacksonXmlProperty(isAttribute = true, localName ="CODE")
    private String code;
    @JacksonXmlProperty(isAttribute = true, localName ="SERIAL")
    private String serial;
    @JacksonXmlProperty(isAttribute = true, localName ="ORDER")
    private String order;
    @JacksonXmlProperty(isAttribute = true, localName ="DESCRIPTION_1")
    private String benennung1;
    @JacksonXmlProperty(isAttribute = true, localName ="DESCRIPTION_2")
    private String benennung2;
    @JacksonXmlProperty(isAttribute = true, localName ="DESCRIPTION_3")
    private String benennung3;
    @JacksonXmlProperty(isAttribute = true, localName ="STATUS_CODE")
    private String statusCode;
    @JacksonXmlProperty(isAttribute = true, localName ="STATUS_INDICATOR")
    private String statusIndicator;
    @JacksonXmlProperty(isAttribute = true, localName ="PRODUCT_NAME")
    private String productName;

    @JacksonXmlProperty(localName = "TABLE")
    private CD1Table cd1Table;
    @JacksonXmlProperty(localName = "TABLE")
    private CD2Table cd2Table;
    @JacksonXmlProperty(localName = "TABLE")
    private CD3Table cd3Table;
}

CD1Table.java

@NoArgsConstructor
@AllArgsConstructor
@JacksonXmlRootElement(localName = "TABLE")
public class CD1Table {
    @JacksonXmlProperty(isAttribute = true, localName = "NAME")
    private String name;

    @JacksonXmlProperty(localName = "ROW")
    private List<CDRow> cd1Row;
}

CD1Row.java

@NoArgsConstructor
@AllArgsConstructor
@JacksonXmlRootElement(localName = "ROW")
public class CD1Row implements RowElement {
    @JacksonXmlProperty(isAttribute = true, localName ="CD1_CODE")
    private String cd1Code;
    @JacksonXmlProperty(isAttribute = true, localName ="CD1_DESCRIPTION")
    private String cd1Description;
}

CD2Table.java

@NoArgsConstructor
@AllArgsConstructor
@JacksonXmlRootElement(localName = "TABLE")
public class CD2Table {
    @JacksonXmlProperty(isAttribute = true, localName = "NAME")
    private String name;
    @JacksonXmlProperty(localName = "ROW")
    private List<CD2Row> cd2Row;
}

CD2Row.java

@NoArgsConstructor
@AllArgsConstructor
@JacksonXmlRootElement(localName = "ROW")
public class CD2Row implements RowElement {
    @JacksonXmlProperty(isAttribute = true, localName ="CD2_CODE")
    private String cd2Code;
    @JacksonXmlProperty(isAttribute = true, localName ="CD2_DESCRIPTION")
    private String cd2Description;
    @JacksonXmlProperty(localName = "TABLE")
    private CD3Table cd3Table;
}

CD3Table.java

@NoArgsConstructor
@AllArgsConstructor
@JacksonXmlRootElement(localName = "TABLE")
public class CD3Table {
    @JacksonXmlProperty(isAttribute = true, localName = "NAME")
    private String name;
}

EFTable.java

@NoArgsConstructor
@AllArgsConstructor
@JacksonXmlRootElement(localName = "TABLE")
public class EFTable {
    @JacksonXmlProperty(isAttribute = true, localName = "NAME")
    private String name;
    @JacksonXmlProperty(isAttribute = true, localName = "CODE")
    private String code;
    @JacksonXmlProperty(localName = "ROW")
    private EFRow efRow;
}

EFRow.java

@NoArgsConstructor
@AllArgsConstructor
@JacksonXmlRootElement(localName = "ROW")
public class EFRow implements RowElement {
    @JacksonXmlProperty(isAttribute = true, localName ="FILE")
    private String file;
    @JacksonXmlProperty(isAttribute = true, localName ="FILE_NAME")
    private String fileName;
    @JacksonXmlProperty(isAttribute = true, localName ="TIMESTAMP")
    private String timestamp;
    @JacksonXmlProperty(localName ="FILE_DATA")
    private String fileData;
}

I would like to know if there is possible way to tackle this scenario along with the other similar scenarios mentioned above, thank you.



Solution 1:[1]

Your main TABLE contains tables, and inner TABLE contains rows. You have different structures to the same tag that is not possible. Create wrapper TABLES for your inner TABLE, and that`s it

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Roma