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

Answers:


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 2014年

如果要Reader与特定的bean类结合使用怎么办?由于没有unmarshall(Reader, Class)方法。例如,有一种方法可以将转换Readerjavax.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它提供了能采用的构造ReaderFileInputStream
Muhd

谢谢!在我的情况下,我需要做一些不同的事情:Person person =(Person)((JAXBElement)unmarshaller.unmarshal(reader))。getValue();
古斯塔沃·阿玛罗

161

或者,如果您需要简单的单线:

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

1
这应该是公认的答案。有点复杂。
bobbel '16

很简单。我完全同意,它必须是公认的答案。
Afaria

5
我实际上不同意以上评论。它当然更容易,但是它可以动态创建上下文,因此即使上下文最终被缓存,它也会对性能产生影响。请谨慎使用。
Crystark '17

那么,如果我们想为解组员提供一个类,那还有什么选择呢?唯一的方法在参数中带有一个(节点,类),这里有一个字符串。
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 "";
}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.