Use JAXB para criar objetos a partir de XML String


174

Como posso usar o código abaixo para cancelar a distribuição de uma string XML e mapeá-la para o objeto JAXB abaixo?

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

Respostas:


282

Para passar o conteúdo XML, você precisa agrupar o conteúdo em a Readere unshalshal que:

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

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

6
Você poderia expandir esta resposta para incluir se a "sequência xml aqui" inclui um envelope SOAP?
— JWiley

e se você quisesse usar um Readerem combinação com uma classe de bean específica? Como não há unmarshall(Reader, Class)método. Por exemplo, existe uma maneira de converter o Readerpara um javax.xml.transform.Source?
— bvdb

2
No meu caso, trabalho como:JAXBElement<MyObject> elemento = (JAXBElement<MyObject>)unmarshaller.unmarshal(reader); MyObject object = elemento.getValue();
— Cesar Miguel

1
@bvdb Você pode usar javax.xml.transform.stream.StreamSourceque tem construtores que levam Reader, Fileou InputStream.
— Muhd

Obrigado! No meu caso, eu precisava fazer um pouco diferente: Person person = (Person) ((JAXBElement) unmarshaller.unmarshal (reader)). GetValue ();
— Gustavo Amaro

161

Ou se você quiser uma única linha:

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

1
Essa deve ser a resposta aceita. Isso é um pouco menos complicado.
— bobbel

Muito simples. Eu concordo totalmente, deve ser a resposta aceita.
— Afaria

5
Na verdade, eu discordo dos comentários acima. Certamente é mais fácil, mas cria o contexto em tempo real para ter impactos no desempenho, mesmo que o contexto acabe sendo armazenado em cache. Use com cuidado.
— Crystark 2/02

Então, qual é a alternativa se queremos fornecer uma classe para o não-agente? O único método leva um (nó, classe) no parâmetro e aqui temos uma string.
— Charles Follet

Com esta versão concisa, não recebo erros de análise, úteis para depurar uma configuração. Provavelmente eu estou faltando alguma coisa ...
— castor

21

Não existe unmarshal(String)método. Você deve usar um Reader:

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

Mas geralmente você está obtendo essa string de algum lugar, por exemplo, um arquivo. Se for esse o caso, é melhor passar por FileReadersi.


3

Se você já possui o xml e vem com mais de um atributo, é possível lidar com ele da seguinte maneira:

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

o método getCharacterDataFromElement é

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

return cd.getData();
}
return "";
}
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.