2010-11-25 12 views
4

Ich habe ein XML, das außerhalb meiner Kontrolle liegt, wie es erzeugt wird. Ich möchte ein Objekt daraus erstellen, indem ich es zu einer von mir handgeschriebenen Klasse abmarsiere.JAXB-Mapping-Elemente mit "unbekanntem" Namen

Ein Ausschnitt aus seiner Struktur wie folgt aussieht:

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

Wie kann ich diesen Fällen umgehen? Natürlich ist die Anzahl der Elemente variabel.

+0

Ist die XML-Struktur haben eine gut definierte Schema? –

+0

Nein. Die Quelle ist ein PHP-REST-Webdienst (was nicht bedeutet, dass dies nicht möglich ist). – bbcooper

Antwort

5

Wenn Sie das folgende Objektmodell dann jeder der unmapped key_ # Elemente wird als Instanz org.w3c.dom.Element markieren gehalten werden:

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

} 

Wenn eines der Elemente Klassen entspricht, die mit einer @ XmlRootElement-Annotation zugeordnet wurden, können Sie @XmlAnyElement (lax = true) verwenden, und die bekannten Elemente werden in die entsprechenden Objekte konvertiert. Ein Beispiel finden:

+0

Ja, das ist die Lösung. Ich änderte es ein wenig (entfernte die Mutatoren) und fügte es als innere statische Klasse ein. Großartig, jetzt geht es weiter zu den nächsten Problemen ... – bbcooper

0

Für diesen einfachen Element, würde ich eine Klasse namens Kategorien erstellen:

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

} 

dann in einem Hauptverfahren oder so, ich habe die Unmarshaller schaffen würde:

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

in der Lage sein Alle Objekte werden abgerufen, ich denke, ich würde alle Elemente in ein Root-Element in einer neuen XML-Datei einfügen und eine Klasse für dieses Root-Element mit der @XmlRootElement Annotation schreiben.

Hoffnung, die hilft, mman

+0

+1, aber Sie müssen keinen Namen für XmlRootElement angeben, da standardmäßig "Kategorien" verwendet werden. Sie müssen auch nicht mit @XmlElement annotieren, da dies der Standardwert ist. –

+0

Nein. Ich weiß, wie man einfache Klassen organisiert und entsorgt. Vielleicht war ich in meiner Frage nicht klar genug. Das obige XML ist NUR ein SNIPPET eines größeren XML. Meine Frage war, wie eine UNBEKANNTE Anzahl von Elementen unter Element zu behandeln. Es kann , also 67 Elemente unter dem Element geben. – bbcooper

+0

Ist der Inhalt des Elements key_ # immer nur ein Textknoten? –

0

Verwenden ähnliche

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