usando parse example complex xml annotations jaxb linked-list

parse - ¿Cómo puedo agregar atributos xml a la clase anotada jaxb XmlElementWrapper?



usando jaxb (3)

La implementación de MOXy JAXB (I''m the tech lead) tiene una extensión ( @XmlPath ) para manejar este caso:

import java.util.*; import javax.xml.bind.annotation.*; import org.eclipse.persistence.oxm.annotations.XmlPath; @XmlRootElement @XmlAccessorType(XmlAccessType.FIELD) public class Root { @XmlPath("myList/@number") private int number; @XmlElementWrapper(name="myList") @XmlElement(name="myElement") private List<String> someList = new LinkedList<String>(); public int getNumber() { return number; } public void setNumber(int number) { this.number = number; } public List<String> getSomeList() { return someList; } public void setSomeList(List<String> someList) { this.someList = someList; } }

Producirá el siguiente XML:

<?xml version="1.0" encoding="UTF-8"?> <root> <myList number="123"> <myElement>FOO</myElement> <myElement>BAR</myElement> </myList> </root>

Cuando este código se ejecuta:

import javax.xml.bind.*; public class Demo { public static void main(String[] args) throws Exception { JAXBContext jc = JAXBContext.newInstance(Root.class); Root root = new Root(); root.setNumber(123); root.getSomeList().add("FOO"); root.getSomeList().add("BAR"); Marshaller marshaller = jc.createMarshaller(); marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); marshaller.marshal(root, System.out); } }

Para que esto funcione con un código JAXB estrictamente estándar, deberá usar un Adaptador XML:

Nota:

Para usar MOXy JAXB debe agregar un archivo llamado jaxb.properties con sus clases de modelo con la siguiente entrada:

javax.xml.bind.context.factory=org.eclipse.persistence.jaxb.JAXBContextFactory

Tengo una clase con una anotación XmlElementWrapper como:

...

@XmlElementWrapper(name="myList") @XmlElements({ @XmlElement(name="myElement") } ) private List<SomeType> someList = new LinkedList();

... Este código produce XML como

<myList> <myElement> </myElement> <myElement> </myElement> <myElement> </myElement> </myList>

hasta ahora tan bueno.

Pero ahora necesito agregar atributos a la etiqueta de lista para obtener XML como

<myList number="2"> <myElement> </myElement> <myElement> </myElement> <myElement> </myElement> </myList>

¿Existe alguna forma inteligente de lograr esto sin crear una nueva clase que contenga la lista?


Si no está usando MOXy o simplemente desea atenerse a las anotaciones de JAXB estándar, puede ampliar la respuesta de Noby para agregar soporte para una clase de envoltorio genérico. La respuesta de Noby solo admite actualmente una lista de cadenas, pero digamos, por ejemplo, que va a utilizar la misma clase de contenedor genérico para varias clases diferentes. En mi ejemplo, quiero crear una clase genérica "PagedList" que se convierta en algo que parezca una lista, pero que también contenga información sobre el desplazamiento de la página y el número total de elementos en la lista no paginada.

El único inconveniente de esta solución es que debe agregar asignaciones de @XmlElement adicionales para cada tipo de clase que se ajustará. Sin embargo, en general, probablemente sea una mejor solución que crear una nueva clase para cada elemento paginable.

@XmlType public class PagedList<T> { @XmlAttribute public int offset; @XmlAttribute public long total; @XmlElements({ @XmlElement(name="order", type=Order.class), @XmlElement(name="address", type=Address.class) // additional as needed }) public List<T> items; } @XmlRootElement(name="customer-profile") public class CustomerProfile { @XmlElement public PagedList<Order> orders; @XmlElement public PagedList<Address> addresses; }

Marcar este ejemplo te daría:

<customer-profile> <order offset="1" total="100"> <order> ... </order> <order> ... </order> <order> ... </order> ... </orders> <addresses offset="1" total="5"> <address> ... </address> <address> ... </address> <address> ... </address> <address> ... </address> <address> ... </address> <addresses> </customer-profile>

Espero que ayude. Esta es la solución en la que me asenté al menos.


Tengo una mejor solución para su pregunta.

Para hacer un objeto Java Xml, use el siguiente código:

import java.util.*; import javax.xml.bind.annotation.*; @XmlRootElement(name="myList") public class Root { private String number; private List<String> someList; @XmlAttribute(name="number") public String getNumber() { return number; } public void setNumber(String number) { this.number = number; } @XmlElement(name="myElement") public List<String> getSomeList() { return someList; } public void setSomeList(List<String> someList) { this.someList = someList; } public Root(String numValue,List<String> someListValue) { this(); this.number = numValue; this.someList = someListValue; } /** * */ public Root() { // TODO Auto-generated constructor stub }

}

Para ejecutar el código anterior utilizando JAXB, use lo siguiente:

import java.util.ArrayList; import java.util.List; import javax.xml.bind.*; public class Demo { public static void main(String[] args) throws Exception { List<String> arg = new ArrayList<String>(); arg.add("FOO"); arg.add("BAR"); Root root = new Root("123", arg); JAXBContext jc = JAXBContext.newInstance(Root.class); Marshaller marshaller = jc.createMarshaller(); marshaller.marshal(root, System.out); } }

Esto producirá el siguiente XML como salida:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <myList number="123"> <myElement>FOO</myElement> <myElement>BAR</myElement> </myList>

Creo que esto es más útil para usted.

Gracias..