Verwenden Sie JAXB, um ein Objekt aus einer XML-Zeichenfolge zu erstellen


174

Wie kann ich den folgenden Code verwenden, um eine XML-Zeichenfolge zu entfernen und sie dem unten stehenden JAXB-Objekt zuzuordnen?

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

Antworten:


282

Um XML-Inhalte zu übergeben, müssen Sie den Inhalt in a Readereinschließen und stattdessen Folgendes entschlüsseln:

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

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

6
Könnten Sie diese Antwort erweitern, um einzuschließen, ob die "XML-Zeichenfolge hier" einen SOAP-Umschlag enthält?
JWiley

Was wäre, wenn Sie eine Readerin Kombination mit einer bestimmten Bohnenklasse verwenden möchten? Da gibt es keine unmarshall(Reader, Class)Methode. Gibt es zB eine Möglichkeit, das Readerin ein umzuwandeln javax.xml.transform.Source?
Bvdb

2
In meinem Fall arbeiten als:JAXBElement<MyObject> elemento = (JAXBElement<MyObject>)unmarshaller.unmarshal(reader); MyObject object = elemento.getValue();
Cesar Miguel

1
@bvdb Sie können verwenden, javax.xml.transform.stream.StreamSourcewelche Konstruktoren Readerhaben File, oder InputStream.
Muhd

Vielen Dank! In meinem Fall musste ich etwas anderes machen: Person person = (Person) ((JAXBElement) unmarshaller.unmarshal (reader)). GetValue ();
Gustavo Amaro

161

Oder wenn Sie einen einfachen Einzeiler wollen:

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

1
Dies sollte die akzeptierte Antwort sein. Das ist etwas weniger kompliziert.
Bobbel

Sehr einfach. Ich stimme vollkommen zu, es muss die akzeptierte Antwort sein.
Afaria

5
Ich bin mit den obigen Kommentaren nicht einverstanden. Es ist sicherlich einfacher, aber es erstellt den Kontext im laufenden Betrieb, sodass es Auswirkungen auf die Leistung haben kann, selbst wenn der Kontext zwischengespeichert wird. Mit Vorsicht verwenden.
Crystark

Was ist also die Alternative, wenn wir dem Unmarshaller eine Klasse bieten wollen? Die einzige Methode ist ein (Knoten, Klasse) Parameter und hier haben wir eine Zeichenfolge.
Charles Follet

Mit dieser übersichtlichen Version erhalte ich keine Analysefehler, die zum Debuggen einer Konfiguration nützlich sind. Wahrscheinlich fehlt mir etwas ...
Biber

21

Es gibt keine unmarshal(String)Methode. Sie sollten Folgendes verwenden Reader:

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

Aber normalerweise erhalten Sie diese Zeichenfolge von irgendwoher, zum Beispiel aus einer Datei. Wenn das der Fall ist, geben Sie es besser FileReaderselbst weiter.


3

Wenn Sie bereits über die XML-Datei verfügen und mehr als ein Attribut haben, können Sie damit wie folgt umgehen:

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

Die Methode getCharacterDataFromElement lautet

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

return cd.getData();
}
return "";
}
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.