Використовуйте 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();
— Сезар Мігель

1
@bvdb Ви можете використовувати , javax.xml.transform.stream.StreamSourceякий має конструктор , які приймають Reader, Fileабо InputStream.
— Мухд

Дякую! У моєму випадку мені потрібно було зробити трохи інше: Person person = (Person) ((JAXBElement) unmarshaller.unmarshal (читач)). GetValue ();
— Густаво Амаро

161

Або якщо ви хочете простий однолінійний:

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

1
Це має бути прийнятою відповіддю. Це трохи менш складно.
— боббел

Дуже просто. Я повністю згоден, це повинна бути прийнята відповідь.
— Afaria

5
Я фактично не згоден з вищезазначеними коментарями. Це, звичайно, простіше, але це створює контекст на льоту, щоб він міг впливати на продуктивність, навіть якщо контекст закінчується кешем. Використовуйте обережно.
— Crystark

То яка альтернатива, якщо ми хочемо надати клас для нерозподільника? Єдиний метод беремо параметр (вузол, клас) і тут у нас є рядок.
— Чарльз Фоллет

У цій стислій версії я не отримую помилок розбору, корисних для налагодження конфігурації. Напевно, мені щось не вистачає ...
— бобр

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 "";
}
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.