2012-11-04 96 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

感谢布莱斯。 出于兴趣,我选择了第一种选择,因为我实际上可以使用单独的对象,以及稍后将它们全部放入集合中。 –

相关问题