问题
Update: Looking for a Jackson or JAXB solution.
After researching a bit about behavior of Jackson, I found that Jackson will always use a wrapper for collections. So probably what I need is not possible to do with Jackson. Hence, added JAXB to title.
Original Question
I need to create POJO for following XML pattern.
<ABWrap>
<A></A>
<B></B>
<A></A>
<B></B>
...
... n times
</ABWrap>
I've tried following POJOs. But these are not generating desired result.
class AB {
@JacksonXmlProperty(localName = "A")
private String A;
@JacksonXmlProperty(localName = "B")
private String B;
}
@JacksonXmlRootElement(localName = "ABWrap")
class ABWrap {
@JacksonXmlElementWrapper(useWrapping = false)
private AB[] ab = new AB[n];
}
I need to maintain the condition that pair of <A></A>
and <B></B>
should come together. Sequence of elements is important.
Following pattern will not work in my case:
<ABWrap>
<A></A>
<A></A>
...
... n times
<B></B>
<B></B>
...
... n times
</ABWrap>
I have been able to achieve second one. But I've not been able to figure out a way to generate the first pattern.
Update on @mart's answer:
I defined ABWrap
, ABInterface
and A
as follows:
@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement(name = "ABWrap")
public class ABWrap {
@XmlElements({@XmlElement(name = "A", type = A.class), @XmlElement(name = "B", type = B.class)})
private List<ABInterface> ab;
}
public interface ABInterface { }
public class A implements ABInterface {
@XmlValue
private String a;
}
B
is defined similar to A
.
main method is as follows:
public class Application {
public static void main(final String[] args) throws JAXBException {
JAXBContext jaxbContext = JAXBContext.newInstance(ABWrap.class);
Marshaller marshaller = jaxbContext.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
A a = new A("a");
B b = new B("b");
ABWrap abWrap = new ABWrap(Arrays.asList(a, b));
marshaller.marshal(abWrap, System.out);
}
}
But this solution failed with following error: (jaxbpoc
is project name)
If a class has @XmlElement property, it cannot have @XmlValue property.
this problem is related to the following location:
at private java.lang.String ...jaxbpoc.A.a
at ...jaxbpoc.A
at private java.util.List ...jaxbpoc.ABWrap.ab
at ...jaxbpoc.ABWrap
this problem is related to the following location:
at public java.lang.String ...A.getA()
at ...jaxbpoc.A
at private java.util.List ...jaxbpoc.ABWrap.ab
at ...jaxbpoc.ABWrap
If a class has @XmlElement property, it cannot have @XmlValue property.
this problem is related to the following location:
at private java.lang.String ...jaxbpoc.B.b
at ...jaxbpoc.B
at private java.util.List ...jaxbpoc.ABWrap.ab
at ...jaxbpoc.ABWrap
....
....
Class has two properties of the same name "a"
this problem is related to the following location:
at public java.lang.String ...jaxbpoc.A.getA()
at ...jaxbpoc.A
at private java.util.List ...jaxbpoc.ABWrap.ab
at ...jaxbpoc.ABWrap
this problem is related to the following location:
....
....
回答1:
You could do this:
@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement(name = "ABWrap")
public class ABWrap {
@XmlElements({
@XmlElement(name="A", type = A.class),
@XmlElement(name="B", type = B.class),
})
private List<Letter> letters;
}
And A, B would look something like this:
public class A implements Letter {
@XmlValue
private String a;
}
And a common interface for A,B that doesn't do much:
public interface Letter { }
Update:
As I mentioned in the comment, I tried XML to POJO and vice versa and it worked. I paste here the simple programs I used to test, so please let me know how it works for you, so I can explore further.
XmlToPojo:
public static void main(String[] args) {
try {
File file = new File("AB.xml");
JAXBContext jaxbContext = JAXBContext.newInstance(ABWrap.class);
Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller();
ABWrap pojo = (ABWrap) jaxbUnmarshaller.unmarshal(file);
} catch (JAXBException e) {
e.printStackTrace();
}
}
And POJO to xml:
public static void main(String[] args) {
try {
JAXBContext jaxbContext = JAXBContext.newInstance(ABWrap.class);
Marshaller marshaller = jaxbContext.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
A a = new A("testA");
B b = new B("testB");
ABWrap abWrap = new ABWrap(Arrays.asList(a, b));
marshaller.marshal(abWrap, System.out);
} catch (JAXBException e) {
e.printStackTrace();
}
}
来源:https://stackoverflow.com/questions/48631031/jaxb-jackson-sequence-of-two-elements-without-parent-tag