Utilisez JAXB pour créer un objet à partir d'une chaîne XML


174

Comment puis-je utiliser le code ci-dessous pour démarseler une chaîne XML et la mapper à l'objet JAXB ci-dessous?

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

Réponses:


282

Pour transmettre du contenu XML, vous devez envelopper le contenu dans un Reader, et démarshal cela à la place:

JAXBContext jaxbContext = JAXBContext.newInstance(Person.class);
Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();

StringReader reader = new StringReader("xml string here");
Person person = (Person) unmarshaller.unmarshal(reader);

6
Pourriez-vous développer cette réponse pour inclure si la "chaîne xml ici" inclut une enveloppe SOAP?
JWiley

Et si vous vouliez utiliser un Readeren combinaison avec une classe de haricots spécifique? Puisqu'il n'y a pas de unmarshall(Reader, Class)méthode. Existe-t-il par exemple un moyen de convertir le Readeren un javax.xml.transform.Source?
bvdb

2
Dans mon cas, travaillez comme:JAXBElement<MyObject> elemento = (JAXBElement<MyObject>)unmarshaller.unmarshal(reader); MyObject object = elemento.getValue();
Cesar Miguel

1
@bvdb Vous pouvez utiliser javax.xml.transform.stream.StreamSourcequi a des constructeurs qui prennent Reader, Fileou InputStream.
Muhd

Merci! Dans mon cas, j'avais besoin de faire un peu différent: Person person = (Person) ((JAXBElement) unmarshaller.unmarshal (reader)). GetValue ();
Gustavo Amaro

162

Ou si vous voulez un simple one-liner:

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

1
Cela devrait être la réponse acceptée. C'est un peu moins compliqué.
bobbel

Très simple. Je suis tout à fait d'accord, ce doit être la réponse acceptée.
Afaria

5
Je ne suis pas d'accord avec les commentaires ci-dessus. C'est certes plus simple, mais cela crée le contexte à la volée, ce qui peut avoir des impacts sur les performances même si le contexte finit par être mis en cache. Utiliser avec précaution.
Crystark

Alors, quelle est l'alternative si nous voulons fournir une classe au démarshaller? La seule méthode prend un (nœud, classe) en paramètre et nous avons ici une chaîne.
Charles Follet

Avec cette version concise, je ne reçois pas d'erreurs d'analyse, utiles pour déboguer une configuration. Il me manque probablement quelque chose ...
castor

21

Il n'y a pas de unmarshal(String)méthode. Vous devez utiliser un Reader:

Person person = (Person) unmarshaller.unmarshal(new StringReader("xml string"));

Mais généralement, vous obtenez cette chaîne de quelque part, par exemple un fichier. Si tel est le cas, mieux vaut passer le FileReaderlui - même.


4

Si vous avez déjà le xml et que plusieurs attributs sont fournis, vous pouvez le gérer comme suit:

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

la méthode getCharacterDataFromElement est

public static String getCharacterDataFromElement(Element e) {
Node child = e.getFirstChild();
if (child instanceof CharacterData) {
CharacterData cd = (CharacterData) child;

return cd.getData();
}
return "";
}
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.