2017-01-09 5 views
3

Je ne peux pas atteindre unmarshall un XML sans connaître l'élément racine. par exemple.Jaxb Unmarshall avec un @XmlRootElement inconnu

<foo> 
    <bar/> 
</foo> 

ou

<bar> 
    <bar/> 
</bar> 

etc ...

Je veux cartographier le résultat unmarshalling sur une classe comme:

// @XmlRootElement ?? 
public class Container 
    implements Serializable 
{ 
    private Bar bar; 
} 

Je suis toujours obligé de fixer le @XmlRootElement .
J'ai cherché comment définir @XmlRootElement à l'exécution sans succès. Une idée?

Je suis en contexte Spring Batch et je peux utiliser le unmarshaller de mon choix.

Note: Je ne peux pas utiliser @XmlElementDecl ou un ObjectFactory comme indiqué here parce Je ne connais pas le nom des noms de racine de possibles.

+0

Qu'attendez-vous pour être le résultat final de votre unmarshalling? –

+0

Merci pour la réponse, j'ai édité la question. –

+0

Copie possible de [Can JAXB gérer plusieurs éléments "racine"?] (Http://stackoverflow.com/questions/12915968/can-jaxb-handle-multiple-root-elements) – ulab

Répondre

2

Adaptée son approche: https://stackoverflow.com/a/33824472/181336

import javax.xml.bind.JAXBContext; 
import javax.xml.bind.JAXBElement; 
import javax.xml.bind.Unmarshaller; 
import javax.xml.bind.annotation.XmlAccessType; 
import javax.xml.bind.annotation.XmlAccessorType; 
import javax.xml.bind.annotation.XmlElement; 
import javax.xml.transform.stream.StreamSource; 
import java.io.ByteArrayInputStream; 
import java.io.InputStream; 
import java.io.Serializable; 

public class Test { 

    @XmlAccessorType(XmlAccessType.PROPERTY) 
    public static class Bar { 
     private String name; 

     public String getName() { 
      return name; 
     } 

     @XmlElement 
     public void setName(String name) { 
      this.name = name; 
     } 
    } 

    @XmlAccessorType(XmlAccessType.PROPERTY) 
    public static class Container implements Serializable { 
     private Bar bar; 

     public Bar getBar() { 
      return bar; 
     } 

     @XmlElement 
     public void setBar(Bar bar) { 
      this.bar = bar; 
     } 
    } 

    public static void main(String[] args) throws Exception { 
     JAXBContext jaxbContext = JAXBContext.newInstance(Container.class); 
     String xml = "<foo><bar><name>Barry</name></bar></foo>"; 
     Unmarshaller unmarshaller = jaxbContext.createUnmarshaller(); 
     InputStream is = new ByteArrayInputStream(xml.getBytes()); 
     JAXBElement<Container> barWrapperElement = unmarshaller.unmarshal(new StreamSource(is), Container.class); 
     Container container = barWrapperElement.getValue(); 

     System.out.println(container.getBar().getName()); 
    } 
} 

Il fonctionne!

+0

Alors l'avez-vous fait fonctionner avec plusieurs éléments racines anonymes? –

+0

Oui, merci. Dans le lot de printemps, j'ai paramétré le 'fragmentRootElementName' de' StaxEventItemReader' en utilisant [late-binding] (http://stackoverflow.com/a/18693233/3042945). Ce 'fragmentRootElementName' est' foo' ou 'bar' dans mon exemple. 'StaxEventItemReader' ne se soucie pas du nom racine du document (par exemple' root', 'root2'). Je vais faire un post avec la solution complète. –

+1

Ce serait cool! –

0

Quelle que XML votre passage a un éléments racine, xml que vous avez mentionné avoir deux fichiers

<foo> 
    <bar/> 
</foo> 

ou

<bar> 
<bar/> 

alors là, vous avez deux noms de racine foo ou barre pour créer deux classes pour chacun si jamais nom de racine, il appellera cette classe

+0

Je ne connais pas à l'avance le nom de la racine. C'est pourquoi je ne peux pas créer une classe en utilisant ce nom. Le XML que j'ai mentionné est une version minimaliste de ce que je veux vraiment réaliser. –