Utilizzare JAXB per creare l'oggetto da una stringa XML


174

Come posso usare il codice qui sotto per annullare la traduzione di una stringa XML e mapparla sull'oggetto JAXB di seguito?

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;
    }
}

Risposte:


282

Per passare il contenuto XML, è necessario racchiudere il contenuto in un Readere non marshal che invece:

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

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

6
Potresti espandere questa risposta per includere se la "stringa xml qui" include una busta SOAP?
JWiley,

cosa succede se si desidera utilizzare un Readerin combinazione con una specifica classe bean? Dal momento che non esiste un unmarshall(Reader, Class)metodo. Ad esempio c'è un modo per convertire il Readerin a javax.xml.transform.Source?
bvdb,

2
Nel mio caso lavoro come:JAXBElement<MyObject> elemento = (JAXBElement<MyObject>)unmarshaller.unmarshal(reader); MyObject object = elemento.getValue();
Cesar Miguel,

1
@bvdb È possibile utilizzare javax.xml.transform.stream.StreamSourceche ha costruttori che prendono Reader, Fileo InputStream.
Muhd,

Grazie! Nel mio caso avevo bisogno di fare un po 'diverso: Person person = (Person) ((JAXBElement) unmarshaller.unmarshal (reader)). GetValue ();
Gustavo Amaro,

162

O se vuoi un semplice one-liner:

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

1
Questa dovrebbe essere la risposta accettata. È un po 'meno complicato.
Bob

Molto semplice. Sono totalmente d'accordo, deve essere la risposta accettata.
Afaria,

5
In realtà non sono d'accordo con i commenti sopra. Certamente è più semplice ma crea il contesto al volo in modo che possa avere impatti sulle prestazioni anche se il contesto finisce per essere memorizzato nella cache. Usare con cautela.
Crystark,

Allora, qual è l'alternativa se vogliamo fornire una classe a unmarshaller? L'unico metodo accetta un (nodo, classe) nel parametro e qui abbiamo una stringa.
Charles Follet,

Con questa versione sintetica non ricevo errori di analisi, utili per eseguire il debug di una configurazione. Probabilmente mi manca qualcosa ...
castoro,

21

Non esiste un unmarshal(String)metodo Dovresti usare un Reader:

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

Ma di solito ricevi quella stringa da qualche parte, ad esempio un file. In tal caso, è meglio che passi lo FileReaderstesso.


4

Se hai già l'xml e arriva più di un attributo, puoi gestirlo come segue:

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());
}

il metodo getCharacterDataFromElement è

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

return cd.getData();
}
return "";
}
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.