是否可以使用多个" root"将多个Java类对象序列化为单个XML文件。元素?

时间:2014-08-15 17:32:38

标签: java xml serialization jaxb

我正在为一个应用程序使用相当复杂和广泛的用户设置。我没有让一个单一的巨型类负责每一个设置,而是明智地决定将它分解为几个更小,更简单的类,每个类都负责一组用户设置。

我希望将每个设置实例存储在一个XML文件中,以简化(我希望)并保持文件数量不会变得非常庞大。

所以我们来问我的问题: 如果我有一个带有单个根元素的XML文件,是否可以在同一根元素中存储多个对象,并在以后提取它们,或者甚至更理想(为了使其更具可读性),对我来说是否可能将多个对象存储在不同根元素名称下的单个XML文件中?例如:可以是以下

@XMLRootElement(name = "Settings")
public class EQLGameSettings{
    @XmlElement(name="PlayerCount")
    final private Integer PlayerCount;
    @XmlElement(name="GameMode")
    final private EQLGameMode Mode;
    @XmlElement(name="WinnerOnNewGame")
    final private Boolean WinnerOnNewGame;
    .
    .
    .
}

在同一个根元素下与它一起存储在同一个XML文件中,以后都会反序列化吗?

@XMLRootElement(name = "Settings")
public class EQLScoreSettings{
    @XmlElement(name="ScoreValue")
    final private Integer ScoreValue;
    @XmlElement(name="PenaltyImposed")
    final private Integer PenaltyImposed;
    @XmlElement(name="VictoryScore")
    final private Integer VictoryScore;
    .
    .
    .
}

然后能够将它们反序列化为各自类的新实例:

JAXBContext EQLGameSettingsContext = JAXBContext.newInstance("EQLGameSettings"),
            EQLScoreSettingsContext = JAXBContext.newInstance("EQLScoreSettings");

Unmarshaller UM = EQLGameSettingsContext.createUnmarshaller();

File settingsXML = new File("path/to/Settings.xml");
EQLGameSettings = (EQLGameSettings) UM.unmarshal(settingsXML);

//And then be able to use the same file with and get a Score Settings instance like so:
UM = EQLScoreSettingsContext.createUnmarshaller();
EQLScoreSettings = (EQLScoreSettings) UM.unmarshal(settingsXML);

那会有用吗?或者甚至试图在同一个XML文件中存储多个对象每次重写一次?或者以下工作?

@XMLRootElement(name = "GameSettings")
public class EQLGameSettings{
    .
    .
    .
}

@XMLRootElement(name = "ScoreSettings")
public class EQLScoreSettings{
    .
    .
    .
}

JAXBContext EQLGameSettingsContext = JAXBContext.newInstance("EQLGameSettings"),
            EQLScoreSettingsContext = JAXBContext.newInstance("EQLScoreSettings");

Unmarshaller UM = EQLGameSettingsContext.createUnmarshaller();

File settingsXML = new File("path/to/Settings.xml");
EQLGameSettings = (EQLGameSettings) UM.unmarshal(settingsXML);

//And then be able to use the same file with and get a Score Settings instance like so:
UM = EQLScoreSettingsContext.createUnmarshaller();
EQLScoreSettings = (EQLScoreSettings) UM.unmarshal(settingsXML);

前面的任何一个或所有工作都可以,或者我只是不得不为每个设置实例生成一个XML文件?

编辑:看起来这不是一个选项。我仍然真的不想经历为每个设置类维护XML文件的痛苦。我的下一个想法是采用每个设置类,而不是使其可序列化。因此,我没有尝试将每个设置都放入XML文件中,而是做了类似的事情:

@XmlRootElement("Settings")
public class MasterSettings{
    @XmlElement("GameSettings")
    EQLGameSettings GameSettings;
    @XmlElement("ScoreSettings")
    EQLScoreSettings ScoreSettings;
}

JAXBContext SettingsContext = JAXBContext.newInstance("MasterSettings");
Unmarshaller UM = SettingsContext.createUnmarshaller();
File SettingsFile = new File("Path/To/Settings.xml");

MasterSettings Settings = (MasterSettings)UM.unmarshal(SettingsFile);

我非常有信心可行,但接下来我需要问的问题是如何设置一个类,以便能够以这种方式序列化?

3 个答案:

答案 0 :(得分:2)

请允许我说事情比您认为的要简单得多:)

编写一个Java类,它反映了您想要存储在一个XML文件中的所有结构。根据你的漫无边际的描述,它可能类似于下面的课程。 (请注意,我演示了如何实现重复元素 - 如果只需要一次,则使用其他模式。)

@XmlRootElement("Settings")
@XmlAccessorType(XmlAccessType.PROPERTY)
public class Settings {
    private List<GameSetting> gameSetting;
    private ScoreSetting scoreSetting;
    @XmlElement
    public List<GameSetting> getGameSetting(){
        if( gameSetting == null ){
            gameSetting = new ArrayList<>();
        }
        return gameSetting;
    }
    @XmlElement
    public ScoreSetting getScoreSetting(){
        return scoreSetting;
    }
    public void setScoreSetting( ScoreSetting value ){
        scoreSetting = value;
    }
}

然后,你有GameSetting和ScoreSetting的类,非常像这个(但你可以省略@XmlRootElement)。

您构建对象层次结构并封送Settings的单个对象 - 这就是全部。解组后,您可以访问proeprties和subproperties。

答案 1 :(得分:1)

无法在一个xml中序列化多个根元素......例如

<parentA>
    <child>
        Text
    </child>
</parentA>
<parentB>
    <child>
        Text
    </child>
</parentB>

你可以这样试试

<wrapperElement>
    <parentA>
        <child>
            Text
        </child>
    </parentA>
    <parentB>
        <child>
            Text
        </child>
    </parentB>
</wrapperElement>

根必须始终是一个。

答案 2 :(得分:-1)

XML基于XSD,因此您无法说出来。

有关详细信息,请参阅this link

this guide

中有一种解决方法