2012-04-11 50 views
1

我想在更大的文檔中映射下面的XML結構,顯然這不是XML的最大用途,但這是我必須使用的。困難的JAXB映射

例簡化了淨度:

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

有這個文檔DTD其中宣佈,將有1-30編號與名稱多達30個不同的畫面元素<picutre[n]/>

我會喜歡做的是,而不是爲每個這些元素創建30個不同的類,稱爲Picture1,Picture2,Picture3 ...等等。我只想使用一個Picture類,並將它用於所有30個獨特的元素名稱。

下面是我到目前爲止嘗試過的。

@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 { 
... 
} 

這會導致getPictures始終返回null。

此外,我試圖改變圖片類的註釋是@XmlElementWrapper(name="picture1")這導致我得到一個從getPictures()返回的列表,但只包含<picture1/>元素,而從來沒有其餘的。

我知道我可以求助於獲取JAXBElement對象的列表,但我寧願不能,如果我可以避免它。任何想法如何我可以映射此?

回答

5

有,你可以處理這個用例幾種方法:

選項#1

你可以通過利用@XmlElements做到以下幾點:

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

} 

選項#2

您可以將您的Details類,如下所示:

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

} 

,然後使用StreamReaderDelegate砍掉的數字後綴:

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

} 

選項#3

如果您正在使用EclipseLink MOXy爲您JAXB (JSR-222)提供商,那麼你可以使用我們添加的@XmlVariableNode擴展:

+1

喜歡的選項2,因爲它允許在未來多於30個元素,但使用選項1現在。謝謝 – 3urdoch 2012-04-11 19:14:34

+1

選項2應謹慎使用:編組不會帶回數字:)但使用類似的代碼,你可以做到這一點。 – 2012-04-14 15:47:03

+0

嗨,Blaise!我遇到了類似的問題,我無法解決。你可以請看看問題https://stackoverflow.com/questions/48908986/jaxb-xml-to-java-mapping? – Aventes 2018-02-21 14:56:37