Используйте JAXB для создания объекта из XML-строки

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;
    }
}
c12
источник

Ответы:

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);
skaffman
источник
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.
Muhd
Спасибо! В моем случае мне нужно было сделать немного иначе: Person person = (Person) ((JAXBElement) unmarshaller.unmarshal (reader)). GetValue ();
Густаво Амаро
162

Или, если вы хотите простой однострочник:

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сам.

Bozho
источник
4

Если у вас уже есть 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 "";
}
Мигель Сапата
источник