unmarshal parse jaxbunmarshaller ejemplo java jaxb

jaxbunmarshaller - parse xml java jaxb



Jaxb complex xml unmarshall (2)

Estoy teniendo problemas para unmarshall xml anidado a continuación. ¿Alguien puede avisar si me falta algo?
body etiqueta del body puede contener cualquier obj anotado Jaxb.
¿Debo crear un adaptador personalizado para ordenar / desasignar dicho xml?

XML de entrada

<?xml version="1.0" encoding="UTF-8"?> <serviceRq xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="serviceRq"> <body> <createRq> <id>1234</id> </createRq> </body> </serviceRq>

Mis clases anotadas por Jaxb son:

@XmlRootElement @XmlAccessorType(XmlAccessType.FIELD) @XmlType(name = "serviceRq") public class ServiceRq{ private Object body; <!-- getters and setters omitted--> }

Aquí, body puede ser cualquier objeto anotado jaxb, en este caso es CreateRq.

@XmlRootElement @XmlAccessorType(XmlAccessType.FIELD) @XmlType(name = "createRq") public class CreateRq{ private String id; <!-- getters and setters omitted--> }

Estoy buscando una forma genérica de admitir cualquier objeto anotado Jaxb en el cuerpo del xml de entrada.


Puede usar @XmlAnyElement(lax=true) y XmlAdapter para manejar este caso de uso:

ServiceRq

import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlRootElement; import javax.xml.bind.annotation.XmlType; import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; @XmlRootElement @XmlAccessorType(XmlAccessType.FIELD) @XmlType(name = "serviceRq") public class ServiceRq{ @XmlJavaTypeAdapter(value=BodyAdapter.class) private Object body; // getters and setters omitted }

BodyAdapter

import javax.xml.bind.annotation.adapters.XmlAdapter; public class BodyAdapter extends XmlAdapter<Body, Object>{ @Override public Object unmarshal(Body v) throws Exception { return v.getValue(); } @Override public Body marshal(Object v) throws Exception { Body body = new Body(); body.setValue(v); return body; } }

Cuerpo

import javax.xml.bind.annotation.XmlAnyElement; public class Body { private Object value; @XmlAnyElement(lax=true) public Object getValue() { return value; } public void setValue(Object value) { this.value = value; } }

CreateRq

import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlRootElement; import javax.xml.bind.annotation.XmlType; @XmlRootElement @XmlAccessorType(XmlAccessType.FIELD) @XmlType(name = "createRq") public class CreateRq{ private String id; // getters and setters omitted }

Manifestación

import java.io.File; import javax.xml.bind.JAXBContext; import javax.xml.bind.Marshaller; import javax.xml.bind.Unmarshaller; public class Demo { public static void main(String[] args) throws Exception { JAXBContext jc = JAXBContext.newInstance(ServiceRq.class); System.out.println(jc); Unmarshaller unmarshaller = jc.createUnmarshaller(); ServiceRq serviceRq = (ServiceRq) unmarshaller.unmarshal(new File("input.xml")); Marshaller marshaller = jc.createMarshaller(); marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); marshaller.marshal(serviceRq, System.out); } }

Para más información


Puede usar @XmlAnyElement(lax=true) y la extensión @XmlPath en EclipseLink JAXB (MOXy) para manejar este caso de uso (Nota: soy el líder de MOXy). Para un enfoque que funcione con cualquier implementación de JAXB ( Metro , MOXy , JaxMe , etc.) ver: Jaxb complex xml unmarshall .

ServiceRq

import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlAnyElement; import javax.xml.bind.annotation.XmlRootElement; import javax.xml.bind.annotation.XmlType; import org.eclipse.persistence.oxm.annotations.XmlPath; @XmlRootElement @XmlAccessorType(XmlAccessType.FIELD) @XmlType(name = "serviceRq") public class ServiceRq{ @XmlPath("body/createRq") @XmlAnyElement(lax=true) private Object body; // getters and setters omitted }

CreateRq

import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlRootElement; import javax.xml.bind.annotation.XmlType; @XmlRootElement @XmlAccessorType(XmlAccessType.FIELD) @XmlType(name = "createRq") public class CreateRq{ private String id; // getters and setters omitted }

Manifestación

import java.io.File; import javax.xml.bind.JAXBContext; import javax.xml.bind.Marshaller; import javax.xml.bind.Unmarshaller; public class Demo { public static void main(String[] args) throws Exception { JAXBContext jc = JAXBContext.newInstance(ServiceRq.class); Unmarshaller unmarshaller = jc.createUnmarshaller(); ServiceRq serviceRq = (ServiceRq) unmarshaller.unmarshal(new File("input.xml")); Marshaller marshaller = jc.createMarshaller(); marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); marshaller.marshal(serviceRq, System.out); } }

jaxb.properties

Para usar MOXy como su proveedor JAXB, debe incluir un archivo llamado jaxb.properties en el mismo paquete que su modelo de dominio con la siguiente entrada:

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

Para más información