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