Reputation: 3585
I'm working with a fairly complex and extensive number of user settings for an application. Rather than have one single megalithic class responsible for every single setting, I've judiciously decided to break it down into several smaller, simpler classes that will each be responsible for a certain set of user settings.
My desire is to store each of these settings instances inside a single XML file for the sake of simplicity (i hope) and to keep the number of files from getting stupidly huge.
So we come to my question: If I have an XML file with a single root element, is it possible to store multiple objects inside that same root element, and extract them later, OR even more ideally (for the sake of making it more readable), is it possible for me to store multiple objects in a single XML file under different root element names? For example: could the following
@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;
.
.
.
}
be stored in the same XML file alongside this under the same root element, and both be deserialized later?
@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;
.
.
.
}
And then be able to deserialize them both into new instances of their respective classes:
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);
Would that work? Or would even trying to store multiple objects in the same XML file rewrite it every single time? Or would the following work?
@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);
Would any or all of the preceding work at all, or am I just going to be stuck with having to generate a single XML file for each settings instance?
EDIT: Looks like that's not an option. I still really do not want to go through the pain of maintaining an XML file for each settings class. My next thought is to take each setting class and instead make it serializable. So instead of trying to fit each setting into an XML file I could instead do something like so:
@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);
I'm pretty confident that will work but then the next question I need to ask is how do I set up a class so that it can be serialized in this fashion?
Upvotes: 2
Views: 2570
Reputation: 31300
Permit me to say that things are much simpler than you appear to think they are :)
Write a Java class that reflects the structure of all you want to store in one XML file. According to your rambling description, it might be something like the class below. (Note that I'm demonstrating how to implement a repeating element - use the other pattern if you need just a single occurrence).
@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;
}
}
Then, you have the classes for GameSetting and ScoreSetting, very much like this one (but you can omit @XmlRootElement
).
You build the object hierarchy and marshal a single object of Settings
- that's all. After unmarshalling you can access the proeprties and subproperties.
Upvotes: 2
Reputation: 52
XML is based on an XSD, for this reason you can't make that you say.
For more information see this link
But there is a workaround in this guide
Upvotes: -1
Reputation: 8282
Isn't possible to serialize multiple root elements in one xml .. e.g
<parentA>
<child>
Text
</child>
</parentA>
<parentB>
<child>
Text
</child>
</parentB>
you can try this way
<wrapperElement>
<parentA>
<child>
Text
</child>
</parentA>
<parentB>
<child>
Text
</child>
</parentB>
</wrapperElement>
The root must be always one.
Upvotes: 1