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

回答:


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)方法がないので。例えば変換する方法がある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取るコンストラクタ持っているReaderFileまたはをInputStream
Muhd 2017

ありがとう!私の場合、私は少し違うことをする必要がありました:Person person =(Person)((JAXBElement)unmarshaller.unmarshal(reader))。getValue();
グスタボアマロ

161

または、単純なワンライナーが必要な場合:

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

1
これは受け入れられる答えになるはずです。それは少し複雑ではありません。
bobbel

とても簡単です。私は完全に同意します、それは受け入れられた答えでなければなりません。
Afaria

5
私は実際には上記のコメントに同意しません。確かに簡単ですが、その場でコンテキストを作成するため、コンテキストがキャッシュされてしまう場合でもパフォーマンスに影響を与える可能性があります。注意して使用してください。
Crystark 2017

それでは、アンマーシャラーにクラスを提供する場合の代替案は何でしょうか?唯一のメソッドはパラメーターで(ノード、クラス)を取り、ここに文字列があります。
Charles Follet 2017

この簡潔なバージョンでは、構成のデバッグに役立つ解析エラーを受け取りません。おそらく何かが足りない...
ビーバー

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.