2012-11-04 134 views
1

我試圖JAXB標註添加到類,以解組XML看起來類似於這樣(注意:我不需要名帥一個java豆成XML ...):閱讀在名稱不同,但均是相同類型的元素列表

<fixture_statistics id="3812596"> 
     <home_team_stats id="2"> 
     <id>2</id> 
     <tackles>58</tackles> 
     <possession>1868</possession> 
     <territory>2603</territory> 
     <minutes_in_22>1316</minutes_in_22> 
     ... 
     </home_team_stats> 
     <guest_team_stats id="21061"> 
     <id>21061</id> 
     <tackles>20</tackles> 
     <possession>3114</possession> 
     <territory>2379</territory> 
     <minutes_in_22>1171</minutes_in_22> 
     ... 
     </guest_team_stats> 
     <home_player_1 id="2306143" teamid="2"> 
     <id>2306143</id> 
     <tackles>3</tackles> 
     <metres_gained>38</metres_gained> 
     ... 
     </home_player_1> 
     <home_player_1 id="2306143" teamid="2"> 
     <id>2306143</id> 
     <tackles>3</tackles> 
     <metres_gained>38</metres_gained> 
     ... 
     </home_player_1> 
     <home_player_1 id="2306143" teamid="2"> 
     <id>2306143</id> 
     <tackles>3</tackles> 
     <metres_gained>38</metres_gained> 
     ... 
     </home_player_1> 
     ... 
     <guest_player_1 id="2306143" teamid="2"> 
     <id>2306143</id> 
     <tackles>3</tackles> 
     <metres_gained>38</metres_gained> 
     ... 
     </guest_player_1> 
     <guest_player_2 id="2306143" teamid="2"> 
     <id>2306143</id> 
     <tackles>3</tackles> 
     <metres_gained>38</metres_gained> 
     ... 
     </guest_player_2> 
     <guest_player_3 id="2306143" teamid="2"> 
     <id>2306143</id> 
     <tackles>3</tackles> 
     <metres_gained>38</metres_gained> 
     ... 
     </guest_player_3> 
     ... 
</fixture_statistics> 

*注忽略一些元素值,因爲我複製並粘貼這個問題...

我已成功地映射「fixture_statistics」,「home_team_stats 「和」guest_team_stats「元素到它們各自的類中,並且我能夠正確解組這些元素,但是我遇到了」home_player_n「和」guest_player_n「元素。我創建了包含了這些元素中找到的屬性的類,但我不知道如何處理的事實要素有不同的名稱 - 「home_player_1」高達「home_player_22」與同爲來賓播放器。

這裏是我的燈具統計類的樣本,我的燈具球員的統計類,以便有人能指出我要去的地方錯了...

@XmlRootElement(name = "fixture_statistics") 
@XmlAccessorType(XmlAccessType.FIELD) 
public class FixtureStatistics { 

    private Collection<FixturePlayerStatistics> homeTeamPlayerStatistics = new ArrayList<>(); 

    private Collection<FixturePlayerStatistics> guestTeamPlayerStatistics = new ArrayList<>(); 
} 

@XmlAccessorType(XmlAccessType.FIELD) 
public class FixturePlayerStatistics { 
    @XmlElement(name="id") 
    private Long playerId; 
    private Integer tackles; 
    @XmlElement(name="metres_gained") 
    private Integer metresGained; 
} 

在FixturePlayerStatistics類我不能添加一個XMlRootElement註釋,因爲該元素可能是44個字符串中的一個,所以我也暫時從FixtureStatistics類的集合中刪除了任何註釋,因爲我確實不確定那裏是什麼。我曾嘗試使用@XmlElementRef,指定所有可能的元素名稱,但那還沒有爲我工作,也無法更改XML,我沒有一個模式來處理,只有從API調用產生的XML。

回答

2

有一些不同的選項來支持這個用例。但總的來說,我會建議避免將索引編入元素名稱的情況。

選項1 - 不同的字段/屬性

一個處理這種使用情況的辦法是爲每個的22間和22家玩家一個獨立的字段/屬性。

package forum13219778; 

import javax.xml.bind.annotation.*; 

@XmlRootElement(name = "fixture_statistics") 
@XmlAccessorType(XmlAccessType.FIELD) 
public class FixtureStatistics { 

    FixturePlayerStatistics guest_player_1; 
    FixturePlayerStatistics guest_player_2; 
    FixturePlayerStatistics guest_player_3; 
    ... 
    FixturePlayerStatistics guest_player_22; 

    FixturePlayerStatistics home_player_1; 
    FixturePlayerStatistics home_player_2; 
    FixturePlayerStatistics home_player_3; 
    ... 
    FixturePlayerStatistics home_player_22;  
} 

選項#2 - 使用SAX XMLFilter脫光_#後綴

如果您的使用情況下,只有與解組,那麼你可以使用SAX XMLFilter脫光獨特的交易每個元素和JAXB註釋中的後綴只需映射到home_playerguest_player。對於XMLFilter例如參見:


OPTION#3 - USE @XmlElementRefsObjectFactory

FixtureStatistics

要使用@XmlElementRefs/@XmlElementRef註釋,您需要更改您的集合以保存JAXBElement<FixturePlayerStatistics>的實例。 JAXBElement將用於保存元素名稱信息。

package forum13219778; 

import java.util.*; 

import javax.xml.bind.JAXBElement; 
import javax.xml.bind.annotation.*; 

@XmlRootElement(name = "fixture_statistics") 
@XmlAccessorType(XmlAccessType.FIELD) 
public class FixtureStatistics { 

    @XmlElementRefs({ 
     @XmlElementRef(name="home_player_1"), 
     @XmlElementRef(name="home_player_2"), 
     @XmlElementRef(name="home_player_3") 
    }) 
    private Collection<JAXBElement<FixturePlayerStatistics>> homeTeamPlayerStatistics = new ArrayList<>(); 

    @XmlElementRefs({ 
     @XmlElementRef(name="guest_player_1"), 
     @XmlElementRef(name="guest_player_2"), 
     @XmlElementRef(name="guest_player_3") 
    }) 
    private Collection<JAXBElement<FixturePlayerStatistics>> guestTeamPlayerStatistics = new ArrayList<>(); 

} 

的ObjectFactory

在結合你需要聲明使用@XmlElementDecl註解根元素@XmlElementRef。這是通過用@XmlRegistry註釋的對象工廠類完成的。

package forum13219778; 

import javax.xml.bind.JAXBElement; 
import javax.xml.bind.annotation.*; 
import javax.xml.namespace.QName; 

@XmlRegistry 
public class ObjectFactory { 

    @XmlElementDecl(name = "home_player_1") 
    public JAXBElement<FixturePlayerStatistics> createHomePlayer1(FixturePlayerStatistics player) { 
     return new JAXBElement<FixturePlayerStatistics>(new QName("home_player_1"), FixturePlayerStatistics.class, player); 
    } 

    @XmlElementDecl(name = "home_player_2") 
    public JAXBElement<FixturePlayerStatistics> createHomePlayer2(FixturePlayerStatistics player) { 
     return new JAXBElement<FixturePlayerStatistics>(new QName("home_player_2"), FixturePlayerStatistics.class, player); 
    } 

    @XmlElementDecl(name = "home_player_3") 
    public JAXBElement<FixturePlayerStatistics> createHomePlayer3(FixturePlayerStatistics player) { 
     return new JAXBElement<FixturePlayerStatistics>(new QName("home_player_3"), FixturePlayerStatistics.class, player); 
    } 

    @XmlElementDecl(name = "guest_player_1") 
    public JAXBElement<FixturePlayerStatistics> createGuestPlayer1(FixturePlayerStatistics player) { 
     return new JAXBElement<FixturePlayerStatistics>(new QName("guest_player_1"), FixturePlayerStatistics.class, player); 
    } 


    @XmlElementDecl(name = "guest_player_2") 
    public JAXBElement<FixturePlayerStatistics> createGuestPlayer2(FixturePlayerStatistics player) { 
     return new JAXBElement<FixturePlayerStatistics>(new QName("guest_player_2"), FixturePlayerStatistics.class, player); 
    } 

    @XmlElementDecl(name = "guest_player_3") 
    public JAXBElement<FixturePlayerStatistics> createGuestPlayer3(FixturePlayerStatistics player) { 
     return new JAXBElement<FixturePlayerStatistics>(new QName("guest_player_3"), FixturePlayerStatistics.class, player); 
    } 

} 

演示

package forum13219778; 

import java.io.File; 
import javax.xml.bind.*; 

public class Demo { 

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

     Unmarshaller unmarshaller = jc.createUnmarshaller(); 
     File xml = new File("src/forum13219778/input.xml"); 
     FixtureStatistics fs = (FixtureStatistics) unmarshaller.unmarshal(xml); 

     Marshaller marshaller = jc.createMarshaller(); 
     marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); 
     marshaller.marshal(fs, System.out); 
    } 

} 
+1

感謝布萊斯。 出於興趣,我選擇了第一種選擇,因爲我實際上可以使用單獨的對象,以及稍後將它們全部放入集合中。 –

相關問題