ใช้ JAXB เพื่อสร้าง Object จาก XML String


174

ฉันจะใช้โค้ดด้านล่างเพื่อยกเลิกการจับสตริง XML กับแผนที่กับวัตถุ JAXB ด้านล่างได้อย่างไร

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

คำตอบ:


282

ในการส่งเนื้อหา XML คุณต้องปิดเนื้อหาในReaderและยกเลิกการปิดบังแทน:

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

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

6
คุณสามารถขยายคำตอบนี้เพื่อรวมได้หรือไม่ถ้า "สตริง xml ที่นี่" มีซอง SOAP?
JWiley

ถ้าคุณต้องการที่จะใช้Readerร่วมกับคลาสถั่วเฉพาะ? เนื่องจากไม่มีunmarshall(Reader, Class)วิธีการ เช่นมีวิธีการแปลงReaderเป็นjavax.xml.transform.Source?
bvdb

2
ในกรณีของฉันทำงานเป็น:JAXBElement<MyObject> elemento = (JAXBElement<MyObject>)unmarshaller.unmarshal(reader); MyObject object = elemento.getValue();
Cesar Miguel

1
@bvdb คุณสามารถใช้javax.xml.transform.stream.StreamSourceซึ่งมีการก่อสร้างที่ใช้Reader, หรือFile InputStream
Muhd

ขอบคุณ! ในกรณีของฉันฉันต้องทำสิ่งต่าง ๆ เล็กน้อย: Person person = (Person) ((JAXBElement) unmarshaller.unmarshal (reader)). getValue ();
Gustavo Amaro

162

หรือถ้าคุณต้องการซับง่าย:

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

1
นี่ควรเป็นคำตอบที่ยอมรับได้ มันซับซ้อนน้อยกว่านี้เล็กน้อย
bobbel

ง่ายมาก. ฉันเห็นด้วยทั้งหมดมันจะต้องเป็นคำตอบที่ได้รับการยอมรับ
Afaria

5
ฉันไม่เห็นด้วยกับความคิดเห็นข้างต้น แน่นอนว่ามันง่ายกว่า แต่สร้างบริบทได้ทันทีเพื่อให้สามารถมีผลกระทบต่อประสิทธิภาพแม้ว่าบริบทจะถูกแคช ใช้ด้วยความระมัดระวัง
Crystark

ดังนั้นทางเลือกคืออะไรถ้าเราต้องการให้คลาสแก่ unmarshaller? วิธีเดียวใช้พารามิเตอร์ (โหนด, คลาส) และที่นี่เรามีสตริง
Charles Follet

ด้วยรุ่นที่กระชับนี้ฉันไม่ได้รับการแยกวิเคราะห์ข้อผิดพลาดมีประโยชน์ในการดีบักการกำหนดค่า น่าจะเป็นฉันหายไปบางสิ่งบางอย่าง ...
ช่องคลอด

21

ไม่มีunmarshal(String)วิธีการ คุณควรใช้Reader:

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

แต่โดยปกติคุณจะได้รับสตริงนั้นจากที่อื่นเช่นไฟล์ หากเป็นเช่นนั้นควรผ่านFileReaderตัวเองดีกว่า


3

หากคุณมี xml อยู่แล้วและมีแอตทริบิวต์มากกว่าหนึ่งรายการคุณสามารถจัดการได้ดังต่อไปนี้:

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

เมธอด getCharacterDataFromElement คือ

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

return cd.getData();
}
return "";
}
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.