2010-11-25 6 views
4

J'ai un XML qui est hors de mon contrôle sur la façon dont il est généré. Je veux en créer un objet en le démêlant à un cours écrit à la main par moi.Éléments de mappage JAXB avec le nom «inconnu»

Un extrait de sa structure ressemble à:

<categories> 
    <key_0>aaa</key_0> 
    <key_1>bbb</key_1> 
    <key_2>ccc</key_2> 
</categories> 

Comment puis-je traiter de tels cas? Bien sûr, le nombre d'éléments est variable.

+0

La structure XML a un schéma bien défini? –

+0

Non. La source est un service web PHP REST (ce qui n'implique pas que ce soit impossible). – bbcooper

Répondre

5

Si vous utilisez le modèle d'objet suivant puis chacun des éléments inexplorées KEY_ # seront gardés comme une instance de org.w3c.dom.Element:

import java.util.List; 
import javax.xml.bind.annotation.XmlAnyElement; 
import javax.xml.bind.annotation.XmlRootElement; 
import org.w3c.dom.Element; 

@XmlRootElement 
public class Categories { 

    private List<Element> keys; 

    @XmlAnyElement 
    public List<Element> getKeys() { 
     return keys; 
    } 

    public void setKeys(List<Element> keys) { 
     this.keys = keys; 
    } 

} 

Si l'un des éléments correspond à des classes mappées avec une annotation @XmlRootElement, vous pouvez utiliser @XmlAnyElement (lax = true) et les éléments connus seront convertis en objets correspondants. Pour un exemple voir:

+0

Oui, c'est la solution. Je l'ai modifié un peu (enlevé les mutateurs) et l'incorpore comme une classe statique interne. Super, maintenant passer aux prochains problèmes ... – bbcooper

0

Pour cet élément simple, je créerais une classe appelée Catégories:

import javax.xml.bind.annotation.XmlRootElement; 

@XmlRootElement 
public class Categories { 

    protected String key_0; 
    protected String key_1; 
    protected String key_2; 

    public String getKey_0() { 
     return key_0; 
    } 

    public void setKey_0(String key_0) { 
     this.key_0 = key_0; 
    } 

    public String getKey_1() { 
     return key_1; 
    } 

    public void setKey_1(String key_1) { 
     this.key_1 = key_1; 
    } 

    public String getKey_2() { 
     return key_2; 
    } 

    public void setKey_2(String key_2) { 
     this.key_2 = key_2; 
    } 

} 

Ensuite, dans une méthode principale ou, je créerais le unmarshaller:

JAXBContext context = JAXBContext.newInstance(Categories.class); 
Unmarshaller um = context.createUnmarshaller(); 
Categories response = (Categories) um.unmarshal(new FileReader("my.xml")); 
// access the Categories object "response" 

Pour pouvoir récupérer tous les objets, je pense que je mettrais tous les éléments à l'intérieur d'un élément racine dans un nouveau fichier xml et écrire une classe pour cet élément racine avec l'annotation @XmlRootElement.

Espoir qui aide, mman

+0

+1, mais vous n'avez pas besoin de spécifier un nom sur XmlRootElement, car il sera par défaut "catégories", vous n'avez pas non plus besoin d'annoter avec @XmlElement car il s'agit de la valeur par défaut. –

+0

Non. Je sais comment marshall et unmarshall des classes simples. Peut-être que je n'étais pas assez clair dans ma question. Le XML ci-dessus est UNIQUEMENT un SNIPPET d'un XML plus grand. Ma question était de savoir comment gérer un nombre inconnu d'éléments ci-dessous élément. Il peut y avoir , donc 67 éléments sous l'élément . – bbcooper

+0

Le contenu de l'élément key_ # est-il toujours juste un nœud de texte? –

0

Utilisez comme cette

 @XmlRootElement 
     @XmlAccessorType(XmlAccessType.FIELD) 
     public static class Categories { 


      @XmlAnyElement 
      @XmlJavaTypeAdapter(ValueAdapter.class) 
      protected List<String> categories=new ArrayList<String>(); 

      public List<String> getCategories() { 
       return categories; 
      } 
      public void setCategories(String value) { 
       this.categories.add(value); 
      } 
     } 

     class ValueAdapter extends XmlAdapter<Object, String>{ 

      @Override 
      public Object marshal(String v) throws Exception { 
       // write code for marshall 
      return null; 
      } 

      @Override 
      public String unmarshal(Object v) throws Exception { 
       Element element = (Element) v; 
       return element.getTextContent(); 
      } 
     } 
Questions connexes