I am working on a demo application to read an XML file. When reading the XML file I am noticing a few XML segments are missing on the java object.
Here is a sample XML I am using:
<person xid="PERSON_LOOP" type="explicit">
<name>Person Loop Information</name>
<segment xid="PER">
<name>Person Header-1</name>
</segment>
<person xid="CHILD_LOOP" type="explicit">
<name>Child Loop Information</name>
<segment xid="CS">
<name>Child Header</name>
</segment>
</person>
<segment xid="PER1">
<name>Person Header-2</name>
</segment>
<segment xid="PER2">
<name>Person Header-3</name>
</segment>
</person>
My java classes are:
LoopDefinition:
import java.util.List;
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlElementWrapper;
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement;
import lombok.Getter;
import lombok.Setter;
@Getter
@Setter
@JacksonXmlRootElement(localName = "person")
public class LoopDefinition {
@JacksonXmlProperty(isAttribute = true, localName = "xid")
private String xid;
@JacksonXmlProperty(localName = "name")
private String name;
@JacksonXmlElementWrapper(useWrapping = false)
@JacksonXmlProperty(localName = "segment")
private List<SegmentDefinition> segments;
@JacksonXmlElementWrapper(useWrapping = false)
@JacksonXmlProperty(localName = "person")
private List<LoopDefinition> loops;
}
Segment Definition:
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement;
import lombok.Getter;
import lombok.Setter;
@Getter
@Setter
@JacksonXmlRootElement(localName = "segment")
public class SegmentDefinition {
@JacksonXmlProperty(isAttribute = true, localName = "xid")
private String xid;
@JacksonXmlProperty(localName = "name")
private String name;
}
After reading the XML file, I noticed that the object is missing segment id PER in the segment list and after debugging I found that the PER segment which was first read to the SegmentDefinition list is being overwritten when subsequent segments on the parent level are read. i.e., PER is being replaced by PER-1 and PER-2 instead of giving PER, PER-1 and PER-2.
Here is a output from the loopDefinition object:
LoopDefinition(xid=PERSON_LOOP, name=Person Loop Information, segments=[SegmentDefinition(xid=PER1, name=Person Header-2), SegmentDefinition(xid=PER2, name=Person Header-3)], loops=[LoopDefinition(xid=CHILD_LOOP, name=Child Loop Information, segments=[SegmentDefinition(xid=CS, name=Child Header)], loops=null)])
It is missing SegmentDefinition(xid=PER, name=Person Header-1)
in the SegmentDefinition list.
Please let me know if I am missing something. Thanks in advance for the help!
I am working on a demo application to read an XML file. When reading the XML file I am noticing a few XML segments are missing on the java object.
Here is a sample XML I am using:
<person xid="PERSON_LOOP" type="explicit">
<name>Person Loop Information</name>
<segment xid="PER">
<name>Person Header-1</name>
</segment>
<person xid="CHILD_LOOP" type="explicit">
<name>Child Loop Information</name>
<segment xid="CS">
<name>Child Header</name>
</segment>
</person>
<segment xid="PER1">
<name>Person Header-2</name>
</segment>
<segment xid="PER2">
<name>Person Header-3</name>
</segment>
</person>
My java classes are:
LoopDefinition:
import java.util.List;
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlElementWrapper;
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement;
import lombok.Getter;
import lombok.Setter;
@Getter
@Setter
@JacksonXmlRootElement(localName = "person")
public class LoopDefinition {
@JacksonXmlProperty(isAttribute = true, localName = "xid")
private String xid;
@JacksonXmlProperty(localName = "name")
private String name;
@JacksonXmlElementWrapper(useWrapping = false)
@JacksonXmlProperty(localName = "segment")
private List<SegmentDefinition> segments;
@JacksonXmlElementWrapper(useWrapping = false)
@JacksonXmlProperty(localName = "person")
private List<LoopDefinition> loops;
}
Segment Definition:
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement;
import lombok.Getter;
import lombok.Setter;
@Getter
@Setter
@JacksonXmlRootElement(localName = "segment")
public class SegmentDefinition {
@JacksonXmlProperty(isAttribute = true, localName = "xid")
private String xid;
@JacksonXmlProperty(localName = "name")
private String name;
}
After reading the XML file, I noticed that the object is missing segment id PER in the segment list and after debugging I found that the PER segment which was first read to the SegmentDefinition list is being overwritten when subsequent segments on the parent level are read. i.e., PER is being replaced by PER-1 and PER-2 instead of giving PER, PER-1 and PER-2.
Here is a output from the loopDefinition object:
LoopDefinition(xid=PERSON_LOOP, name=Person Loop Information, segments=[SegmentDefinition(xid=PER1, name=Person Header-2), SegmentDefinition(xid=PER2, name=Person Header-3)], loops=[LoopDefinition(xid=CHILD_LOOP, name=Child Loop Information, segments=[SegmentDefinition(xid=CS, name=Child Header)], loops=null)])
It is missing SegmentDefinition(xid=PER, name=Person Header-1)
in the SegmentDefinition list.
Please let me know if I am missing something. Thanks in advance for the help!
Share Improve this question edited Mar 14 at 18:34 Vamsi asked Mar 14 at 17:49 VamsiVamsi 7013 gold badges12 silver badges26 bronze badges1 Answer
Reset to default 1Based on this bug report, you can not arbitrarily split elements of an array around other properties. But there is a workaround, you have to override the setter method of segments
list as follows:
@Getter
@Setter
@ToString
@JacksonXmlRootElement(localName = "person")
static class LoopDefinition {
@JacksonXmlProperty(isAttribute = true, localName = "xid")
private String xid;
@JacksonXmlProperty(localName = "name")
private String name;
@JacksonXmlElementWrapper(useWrapping = false)
@JacksonXmlProperty(localName = "segment")
private List<SegmentDefinition> segments;
@JacksonXmlElementWrapper(useWrapping = false)
@JacksonXmlProperty(localName = "person")
private List<LoopDefinition> loops;
// overrides lombok setter
public void setSegments(List<SegmentDefinition> value){
if (segments == null){
segments = new ArrayList<>();
}
segments.addAll(value);
}
}