Gunakan JAXB untuk membuat Objek dari XML String


174

Bagaimana saya bisa menggunakan kode di bawah ini untuk menghapus string XML dan memetakannya ke objek JAXB di bawah ini?

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

Jawaban:


282

Untuk meneruskan konten XML, Anda harus membungkus konten dalam Reader, dan menghapusnya:

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

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

6
Bisakah Anda memperluas jawaban ini untuk menyertakan jika "string xml di sini" termasuk amplop SOAP?
JWiley

bagaimana jika Anda ingin menggunakan Readerkombinasi dengan kelas kacang tertentu? Karena tidak ada unmarshall(Reader, Class)metode. Misalnya apakah ada cara untuk mengonversi Readerke javax.xml.transform.Source?
bvdb

2
Dalam kasus saya bekerja sebagai:JAXBElement<MyObject> elemento = (JAXBElement<MyObject>)unmarshaller.unmarshal(reader); MyObject object = elemento.getValue();
Cesar Miguel

1
@bvdb Anda dapat menggunakan javax.xml.transform.stream.StreamSourceyang memiliki konstruktor yang mengambil Reader, Fileatau InputStream.
Muhd

Terima kasih! Dalam kasus saya, saya perlu melakukan sedikit berbeda: Person person = (Person) ((JAXBElement) unmarshaller.unmarshal (reader)). GetValue ();
Gustavo Amaro

161

Atau jika Anda menginginkan one-liner sederhana:

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

1
Ini harus menjadi jawaban yang diterima. Itu tidak terlalu rumit.
bobbel

Sangat sederhana. Saya setuju sepenuhnya, itu pasti jawaban yang diterima.
Afaria

5
Saya sebenarnya tidak setuju dengan komentar di atas. Ini tentu lebih mudah tetapi menciptakan konteks dengan cepat sehingga dapat memiliki dampak kinerja bahkan jika konteksnya akhirnya di-cache. Gunakan dengan hati-hati.
Crystark

Jadi apa alternatifnya jika kita ingin memberikan kelas kepada unmarshaller? Satu-satunya metode mengambil parameter (node, class) dan di sini kita memiliki sebuah string.
Charles Follet

Dengan versi ringkas ini saya tidak menerima kesalahan penguraian, berguna untuk men-debug konfigurasi. Mungkin aku kehilangan sesuatu ...
berang

21

Tidak ada unmarshal(String)metode. Anda harus menggunakan Reader:

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

Tetapi biasanya Anda mendapatkan string itu dari suatu tempat, misalnya file. Jika itu masalahnya, lebih baik lewati saja FileReader.


3

Jika Anda sudah memiliki xml, dan datang lebih dari satu atribut, Anda dapat menanganinya sebagai berikut:

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

metode getCharacterDataFromElement adalah

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

return cd.getData();
}
return "";
}
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.