2012-04-11 1 views
1

Ich versuche, die folgende XML-Struktur in einem größeren Dokument abzuzubilden, eindeutig ist dies nicht der größte Einsatz von XML immer, aber das ist, was ich mit zu arbeiten.Schwierig JAXB Mapping

Beispiel für Klarheit vereinfacht:

<details> 
    <pictures> 
     <picture1> 
     http://domain.com/path/picture1.jpg 
     </picture1> 
     <picture2> 
     http://domain.com/path/picture2.jpg 
     </picture2> 
     <picture3> 
     http://domain.com/path/picture3.jpg 
     </picture3> 
     <picture4> 
     http://domain.com/path/picture4.jpg 
     </picture4> 
     <picture5> 
     http://domain.com/path/picture5.jpg 
     </picture5> 
     <picture6> 
     http://domain.com/path/picture6.jpg 
     </picture6> 
     <picture7> 
     http://domain.com/path/picture7.jpg 
     </picture7> 
    </pictures> 
    </details> 

Es gibt eine DTD für dieses Dokument, das, dass es Elemente werden bis zu 30 verschiedene Bild 1-30 mit den Namen <picutre[n]/>

Was würde ich nummerierte erklärt wie zu tun ist, anstatt zu schaffen 30 verschiedene Klassen für jedes dieser Elemente Bild1, Bild2, Picture3 ... und so weiter genannt. Ich möchte nur eine einzelne Picture-Klasse verwenden und sie für alle 30 eindeutigen Elementnamen verwenden.

Unten ist, was ich bisher versucht habe.

@XmlRootElement 
public class Details { 

    ... 

    @XmlElementWrapper 
    @XmlElementRefs({ 
     @XmlElementRef(name="picture1", type=Picture.class), 
     @XmlElementRef(name="picture2", type=Picture.class), 
     @XmlElementRef(name="picture3", type=Picture.class), 
     @XmlElementRef(name="picture4", type=Picture.class), 
     @XmlElementRef(name="picture5", type=Picture.class), 
     @XmlElementRef(name="picture6", type=Picture.class), 
     @XmlElementRef(name="picture7", type=Picture.class), 
     @XmlElementRef(name="picture8", type=Picture.class), 
     @XmlElementRef(name="picture9", type=Picture.class), 
     @XmlElementRef(name="picture10", type=Picture.class), 
     @XmlElementRef(name="picture11", type=Picture.class), 
     @XmlElementRef(name="picture12", type=Picture.class), 
     @XmlElementRef(name="picture13", type=Picture.class), 
     @XmlElementRef(name="picture14", type=Picture.class), 
     @XmlElementRef(name="picture15", type=Picture.class), 
     @XmlElementRef(name="picture16", type=Picture.class), 
     @XmlElementRef(name="picture17", type=Picture.class), 
     @XmlElementRef(name="picture18", type=Picture.class), 
     @XmlElementRef(name="picture19", type=Picture.class), 
     @XmlElementRef(name="picture20", type=Picture.class), 
     @XmlElementRef(name="picture21", type=Picture.class), 
     @XmlElementRef(name="picture22", type=Picture.class), 
     @XmlElementRef(name="picture23", type=Picture.class), 
     @XmlElementRef(name="picture24", type=Picture.class), 
     @XmlElementRef(name="picture25", type=Picture.class), 
     @XmlElementRef(name="picture26", type=Picture.class), 
     @XmlElementRef(name="picture27", type=Picture.class), 
     @XmlElementRef(name="picture28", type=Picture.class), 
     @XmlElementRef(name="picture29", type=Picture.class), 
     @XmlElementRef(name="picture30", type=Picture.class) 
    }) 
    public List<Picture> getPictures() { 
     return this.pictures; 
    } 

    public void setPictures(List<Pictures> pictures) { 
     this.pictures = pictures; 
    } 

    ... 

} 

@XmlElementWrapper 
public class Picture { 
... 
} 

Dies bewirkt, dass getPictures immer null zurückgibt.

Zusätzlich habe ich versucht, die Annotation in der Picture-Klasse zu @XmlElementWrapper(name="picture1") zu ändern, was dazu führte, dass ich eine Liste von getPictures() erhielt, aber immer nur das Element <picture1/> und nie den Rest.

Ich weiß, dass ich immer eine Liste von JAXBElement greifen kann Objekte stattdessen aber ich würde lieber nicht, wenn ich es vermeiden kann. Irgendwelche Ideen, wie ich das abbilden kann?

Antwort

5

Es gibt ein paar Möglichkeiten, wie Sie diesen Anwendungsfall umgehen konnte:

Option # 1

Sie könnten durch die folgende tun @XmlElements Nutzung:

package forum10109418; 

import java.util.List; 
import javax.xml.bind.annotation.*; 

@XmlRootElement 
public class Details { 

    private List<Picture> pictures; 

    @XmlElementWrapper 
    @XmlElements({ 
     @XmlElement(name="picture1", type=Picture.class), 
     @XmlElement(name="picture2", type=Picture.class), 
     @XmlElement(name="picture3", type=Picture.class), 
     @XmlElement(name="picture4", type=Picture.class), 
     @XmlElement(name="picture5", type=Picture.class), 
     @XmlElement(name="picture6", type=Picture.class), 
     @XmlElement(name="picture7", type=Picture.class), 
     @XmlElement(name="picture8", type=Picture.class), 
     @XmlElement(name="picture9", type=Picture.class), 
     @XmlElement(name="picture10", type=Picture.class), 
     @XmlElement(name="picture11", type=Picture.class), 
     @XmlElement(name="picture12", type=Picture.class), 
     @XmlElement(name="picture13", type=Picture.class), 
     @XmlElement(name="picture14", type=Picture.class), 
     @XmlElement(name="picture15", type=Picture.class), 
     @XmlElement(name="picture16", type=Picture.class), 
     @XmlElement(name="picture17", type=Picture.class), 
     @XmlElement(name="picture18", type=Picture.class), 
     @XmlElement(name="picture19", type=Picture.class), 
     @XmlElement(name="picture20", type=Picture.class), 
     @XmlElement(name="picture21", type=Picture.class), 
     @XmlElement(name="picture22", type=Picture.class), 
     @XmlElement(name="picture23", type=Picture.class), 
     @XmlElement(name="picture24", type=Picture.class), 
     @XmlElement(name="picture25", type=Picture.class), 
     @XmlElement(name="picture26", type=Picture.class), 
     @XmlElement(name="picture27", type=Picture.class), 
     @XmlElement(name="picture28", type=Picture.class), 
     @XmlElement(name="picture29", type=Picture.class), 
     @XmlElement(name="picture30", type=Picture.class) 
    }) 

    public List<Picture> getPictures() { 
     return this.pictures; 
    } 

    public void setPictures(List<Picture> pictures) { 
     this.pictures = pictures; 
    } 

} 

Option # 2

Sie könnten Karte Ihre 01.234.Klasse wie folgt:

package forum10109418; 

import java.util.List; 
import javax.xml.bind.annotation.*; 

@XmlRootElement 
public class Details { 

    private List<Picture> pictures; 

    @XmlElementWrapper 
    @XmlElement(name="picture") 
    public List<Picture> getPictures() { 
     return this.pictures; 
    } 

    public void setPictures(List<Picture> pictures) { 
     this.pictures = pictures; 
    } 

} 

Und dann ein StreamReaderDelegate Sie über das numerische Suffix abzuhacken:

package forum10109418; 

import java.io.FileInputStream; 
import javax.xml.bind.*; 
import javax.xml.stream.*; 
import javax.xml.stream.util.StreamReaderDelegate; 

public class Demo { 

    public static void main(String[] args) throws Exception { 
     JAXBContext jc = JAXBContext.newInstance(Details.class); 

     XMLInputFactory xif = XMLInputFactory.newFactory(); 
     XMLStreamReader xsr = xif.createXMLStreamReader(new FileInputStream("src/forum10109418/input.xml")); 
     xsr = new StreamReaderDelegate(xsr) { 
      @Override 
      public String getLocalName() { 
       String localName = super.getLocalName(); 
       if(localName.startsWith("picture") && !localName.equals("pictures")) { 
        return "picture"; 
       } 
       return localName; 
      } 

     }; 
     Unmarshaller unmarshaller = jc.createUnmarshaller(); 
     Details details = (Details) unmarshaller.unmarshal(xsr); 
     System.out.println(details.getPictures().size()); 
    } 

} 

Option # 3

Wenn Sie EclipseLink MOXy als JAXB (JSR-222) Anbieter verwenden, dann könnten Sie die @XmlVariableNode Erweiterung verwenden, die wir hinzugefügt:

+1

Wie Option 2, da es für mehr als 30 Elemente in der Zukunft ermöglicht, aber 1 jetzt mit Option. Danke – 3urdoch

+1

Option 2 sollte mit Vorsicht verwendet werden: Marshalling bringt keine Zahlen zurück :) Aber mit analogem Code können Sie dies geschehen lassen. –

+0

Hallo Blaise! Ich habe ein ähnliches Problem, das ich nicht lösen kann. Können Sie einen Blick Frage nehmen Sie bitte https://stackoverflow.com/questions/48908986/jaxb-xml-to-java-mapping? – Aventes