Використовуйте 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.