Use JAXB para crear objetos a partir de cadenas XML


174

¿Cómo puedo usar el siguiente código para desarmar una cadena XML y asignarla al objeto JAXB a continuación?

JAXBContext jaxbContext = JAXBContext.newInstance(Person.class);
Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
Person person = (Person) unmarshaller.unmarshal("xml string here");

@XmlRootElement(name = "Person")
public class Person {
    @XmlElement(name = "First-Name")
    String firstName;
    @XmlElement(name = "Last-Name")
    String lastName;
    public String getFirstName() {
        return firstName;
    }
    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }
    public String getLastName() {
        return lastName;
    }
    public void setLastName(String lastName) {
        this.lastName = lastName;
    }
}

Respuestas:


282

Para pasar contenido XML, debe envolver el contenido en un Reader, y desmarcar eso en su lugar:

JAXBContext jaxbContext = JAXBContext.newInstance(Person.class);
Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();

StringReader reader = new StringReader("xml string here");
Person person = (Person) unmarshaller.unmarshal(reader);

66
¿Podría ampliar esta respuesta para incluir si la "cadena xml aquí" incluye un sobre SOAP?
JWiley

¿Qué pasaría si quisiera usar una Readercombinación con una clase de bean específica? Ya que no hay unmarshall(Reader, Class)método. Por ejemplo, ¿hay alguna manera de convertir el Readera a javax.xml.transform.Source?
bvdb

2
En mi caso trabajo como:JAXBElement<MyObject> elemento = (JAXBElement<MyObject>)unmarshaller.unmarshal(reader); MyObject object = elemento.getValue();
Cesar Miguel

1
@bvdb Puede usar javax.xml.transform.stream.StreamSourceque tiene constructores que toman Reader, Fileo InputStream.
Muhd

¡Gracias! En mi caso, necesitaba hacer un poco diferente: Person person = (Person) ((JAXBElement) unmarshaller.unmarshal (reader)). GetValue ();
Gustavo Amaro

161

O si quieres una línea simple:

Person person = JAXB.unmarshal(new StringReader("<?xml ..."), Person.class);

1
Esta debería ser la respuesta aceptada. Eso es un poco menos complicado.
bobbel

Muy simple. Estoy totalmente de acuerdo, debe ser la respuesta aceptada.
Afaria

55
De hecho, no estoy de acuerdo con los comentarios anteriores. Ciertamente es más fácil, pero crea el contexto sobre la marcha para que pueda tener un impacto en el rendimiento, incluso si el contexto termina en caché. Usar con precaución.
Crystark

Entonces, ¿cuál es la alternativa si queremos proporcionar una clase para el desmonteador? El único método toma un parámetro (nodo, clase) y aquí tenemos una cadena.
Charles Follet

Con esta versión concisa no recibo errores de análisis, útiles para depurar una configuración. Probablemente me estoy perdiendo algo ...
castor

21

No hay unmarshal(String)método Debe usar un Reader:

Person person = (Person) unmarshaller.unmarshal(new StringReader("xml string"));

Pero generalmente obtienes esa cadena de algún lugar, por ejemplo, un archivo. Si ese es el caso, mejor pasa el FileReadersí mismo.


3

Si ya tiene el xml y viene con más de un atributo, puede manejarlo de la siguiente manera:

String output = "<ciudads><ciudad><idCiudad>1</idCiudad>
<nomCiudad>BOGOTA</nomCiudad></ciudad><ciudad><idCiudad>6</idCiudad>
<nomCiudad>Pereira</nomCiudad></ciudads>";
DocumentBuilder db = DocumentBuilderFactory.newInstance()
    .newDocumentBuilder();
InputSource is = new InputSource();
is.setCharacterStream(new StringReader(output));

Document doc = db.parse(is);
NodeList nodes = ((org.w3c.dom.Document) doc)
    .getElementsByTagName("ciudad");

for (int i = 0; i < nodes.getLength(); i++) {           
    Ciudad ciudad = new Ciudad();
    Element element = (Element) nodes.item(i);

    NodeList name = element.getElementsByTagName("idCiudad");
    Element element2 = (Element) name.item(0);
    ciudad.setIdCiudad(Integer
        .valueOf(getCharacterDataFromElement(element2)));

    NodeList title = element.getElementsByTagName("nomCiudad");
    element2 = (Element) title.item(0);
    ciudad.setNombre(getCharacterDataFromElement(element2));

    ciudades.getPartnerAccount().add(ciudad);
}
}

for (Ciudad ciudad1 : ciudades.getPartnerAccount()) {
System.out.println(ciudad1.getIdCiudad());
System.out.println(ciudad1.getNombre());
}

el método getCharacterDataFromElement es

public static String getCharacterDataFromElement(Element e) {
Node child = e.getFirstChild();
if (child instanceof CharacterData) {
CharacterData cd = (CharacterData) child;

return cd.getData();
}
return "";
}
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.