java xpath jaxb unmarshalling

java - Desmaterializando un XML usando la expresión Xpath y jaxb



unmarshalling (3)

Si lo único que desea es el nombre de la calle, simplemente use una expresión XPath para obtenerlo como una cadena, y olvídese de JAXB: el complejo mecanismo JAXB no agrega ningún valor.

import javax.xml.xpath.*; import org.xml.sax.InputSource; public class XPathDemo { public static void main(String[] args) throws Exception { XPathFactory xpf = XPathFactory.newInstance(); XPath xpath = xpf.newXPath(); InputSource xml = new InputSource("src/forum17141154/input.xml"); String result = (String) xpath.evaluate("/root/record/AddressDetails/street", xml, XPathConstants.STRING); System.out.println(result); } }

Soy nuevo en JAXB y me gustaría saber si hay una manera de deshacer un XML de mi objeto de respuesta pero utilizando expresiones xpath. El problema es que estoy llamando a un servicio web de terceros y la respuesta que recibo tiene muchos detalles. No deseo asignar todos los detalles en el XML a mi objeto de respuesta. Solo deseo mapear algunos detalles del xml con los cuales puedo obtener el uso de expresiones XPath específicas y asignarlas a mi objeto de respuesta. ¿Hay alguna anotación que pueda ayudarme a lograr esto?

Por ejemplo, considere la siguiente respuesta

<root> <record> <id>1</id> <name>Ian</name> <AddressDetails> <street> M G Road </street> </AddressDetails> </record> </root>

Solo estoy interesado en recuperar el nombre de la calle, así que quiero usar la expresión xpath para obtener el valor de la calle usando ''root / record / AddressDetails / street'' y asignarlo a mi objeto de respuesta

public class Response{ // How do i map this in jaxb, I do not wish to map record,id or name elements String street; //getter and setters .... }

Gracias


Si quiere hacer un mapa en el medio de un documento XML, puede hacer lo siguiente:

Código de demostración

Puede usar un analizador StAX para avanzar a la parte del documento que desea desasignar, y luego desmantelar el XMLStreamReader desde allí.

import javax.xml.bind.*; import javax.xml.stream.*; import javax.xml.transform.stream.StreamSource; public class Demo { public static void main(String[] args) throws Exception { JAXBContext jc = JAXBContext.newInstance(Response.class); XMLInputFactory xif = XMLInputFactory.newFactory(); StreamSource xml = new StreamSource("src/forum17141154/input.xml"); XMLStreamReader xsr = xif.createXMLStreamReader(xml); while(!(xsr.isStartElement() && xsr.getLocalName().equals("AddressDetails"))) { xsr.next(); } Unmarshaller unmarshaller = jc.createUnmarshaller(); JAXBElement<Response> response = unmarshaller.unmarshal(xsr, Response.class); Marshaller marshaller = jc.createMarshaller(); marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); marshaller.marshal(response, System.out); } }

Respuesta

Las asignaciones en el objeto de dominio se realizan en relación con el fragmento del documento XML al que se está asignando.

import javax.xml.bind.annotation.*; @XmlAccessorType(XmlAccessType.FIELD) public class Response{ String street; //getter and setters }

Salida

<?xml version="1.0" encoding="UTF-8"?> <AddressDetails> <street> M G Road </street> </AddressDetails>

Para más información


Nota: soy el líder de EclipseLink JAXB (MOXy) y miembro del grupo de expertos JAXB (JST-222) .

Puede usar la extensión @XmlPath de @XmlPath para este caso de uso.

Respuesta

import javax.xml.bind.annotation.*; import org.eclipse.persistence.oxm.annotations.XmlPath; @XmlRootElement(name="root") @XmlAccessorType(XmlAccessType.FIELD) public class Response{ @XmlPath("record/AddressDetails/street/text()") String street; //getter and setters }

jaxb.properties

Para utilizar 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 (consulte: http://blog.bdoughan.com/2011/05/specifying-eclipselink- moxy-as-your.html )

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

Manifestación

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

Salida

<?xml version="1.0" encoding="UTF-8"?> <root> <record> <AddressDetails> <street> M G Road </street> </AddressDetails> </record> </root>

Para más información