is anybody try to marshal JAXB object with recurisive referency? I have following class:
public class A {
private Long id;
private String name;
private List<A> aList;
}
and I'd like to marshall it to:
<a>
<a>
<a>...</a>
...
</a>
...
</a>
I'm using maven plugin to auto generate JAXB class from XSD. Any suggestions?
Below is how you can support this use case starting from your XML schema.
XML SCHEMA (schema.xsd)
The following XML schema is based on the comment you made to a previous answer (http://stackoverflow.com/a/14317461/383861).
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://www.example.org"
xmlns:tns="http://www.example.org"
elementFormDefault="qualified">
<xs:element name="b">
<xs:complexType>
<xs:sequence>
<xs:element ref="tns:a" maxOccurs="unbounded" />
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="a">
<xs:complexType>
<xs:sequence>
<xs:element name="id" type="xs:long" />
<xs:sequence>
<xs:element ref="tns:a" minOccurs="0" maxOccurs="10" />
</xs:sequence>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
GENERATED MODEL
The following code was generated using the xjc
tool. The get/set methods and comments have been removed to save space.
A
package org.example;
import java.util.List;
import javax.xml.bind.annotation.*;
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "", propOrder = {
"id",
"a"
})
@XmlRootElement(name = "a")
public class A {
protected long id;
protected List<A> a;
}
B
package org.example;
import java.util.List;
import javax.xml.bind.annotation.*;
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "", propOrder = {
"a"
})
@XmlRootElement(name = "b")
public class B {
@XmlElement(required = true)
protected List<A> a;
}
package-info
@javax.xml.bind.annotation.XmlSchema(
namespace = "http://www.example.org",
elementFormDefault = javax.xml.bind.annotation.XmlNsForm.QUALIFIED)
package org.example;
ObjectFactory
package org.example;
import javax.xml.bind.annotation.XmlRegistry;
@XmlRegistry
public class ObjectFactory {
public ObjectFactory() {
}
public B createB() {
return new B();
}
public A createA() {
return new A();
}
}
DEMO CODE
import java.io.File;
import javax.xml.bind.*;
import org.example.A;
public class Demo {
public static void main(String[] args) throws Exception {
JAXBContext jc = JAXBContext.newInstance("org.example");
Unmarshaller unmarshaller = jc.createUnmarshaller();
File xml = new File("src/forum14306965/input.xml");
A a = (A) unmarshaller.unmarshal(xml);
Marshaller marshaller = jc.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
marshaller.marshal(a, System.out);
}
}
INPUT (input.xml)/OUTPUT
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<a xmlns="http://www.example.org">
<id>1</id>
<a>
<id>2</id>
<a>
<id>3</id>
</a>
</a>
</a>
You could do the following:
A
You can use the @XmlElementRef
annotation on the aList
field so that the element it uses comes from the @XmlRootElement
annotation on the A
class.
@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class A {
private Long id;
private String name;
@XmlElementRef
private List<A> aList;
}
Demo
Below is some sample code to prove that everything works.
import java.io.File;
import javax.xml.bind.*;
public class Demo {
public static void main(String[] args) throws Exception {
JAXBContext jc = JAXBContext.newInstance(A.class);
Unmarshaller unmarshaller = jc.createUnmarshaller();
File xml = new File("src/forum14306965/input.xml");
A a = (A) unmarshaller.unmarshal(xml);
Marshaller marshaller = jc.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
marshaller.marshal(a, System.out);
}
}
input.xml/Output
Below is the input to and output from running the demo code.
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<a>
<id>1</id>
<name>A</name>
<a>
<id>2</id>
<name>B</name>
<a>
<id>3</id>
<name>C</name>
</a>
</a>
</a>
XML Schema
Below is the XML schema that corresponds to this model. You could generate the model from it or start from the Java model.
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<xs:schema version="1.0" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="a" type="a"/>
<xs:complexType name="a">
<xs:sequence>
<xs:element name="id" type="xs:long" minOccurs="0"/>
<xs:element name="name" type="xs:string" minOccurs="0"/>
<xs:element ref="a" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
</xs:schema>
来源:https://stackoverflow.com/questions/14306965/jaxb-marshalling-with-recursive-dependency