Search Unity

XML serialization puzzle

Discussion in 'Scripting' started by Aquamarine222, Jul 17, 2019.

  1. Aquamarine222

    Aquamarine222

    Joined:
    Apr 21, 2019
    Posts:
    2
    This has been killing me for the whole of today.

    I've just recently introduced myself to XML and I'm trying to use an XML database to store parts of customizable boats.
    Code (CSharp):
    1. <moduledatabase>
    2.     <HullConfig>
    3.  
    4.         <name = "Small Hull">
    5.             <modulecost> 10 </modulecost>
    6.             <effect> 1 </effect>
    7.         </name>
    8.  
    9.         <name = "Medium Hull">
    10.             <modulecost> 15 </modulecost>
    11.             <effect> 1.5 </effect>
    12.         </name>
    13.  
    14.     </HullConfig>
    15. </moduledatabase>
    Ideally this database wouldn't just contain hull sections, but also any other customizable sections, I.e. <EngineConfig></EngineConfig>, and pull lists of the different potential configurations when a player is browsing them.

    Unfortunately every tutorial I've come across involving pulling multiple items from the database only touches on pulling items of a single 'category' (array), and tells me to do it like so:
    Code (CSharp):
    1. [XmlRoot("moduledatabase")]
    2. public class ModulePuller {
    3.     [XmlArray("HullConfig")]
    4.     [XmlArrayItem("name")]
    5.     public List<Module> modules = new List<Module>();
    6. }
    7.  
    While this works perfectly for pulling a list of all hull configurations, it's apparently impossible to selectively alter the XMLArray variables as they are static (it throws CS0120) - so if/when I add more categories of modules (such as an <EngineConfig></EngineConfig>) I'm unable to tell the XmlArray/deserializer to change the category of items it's meant to pull.

    The only feasible workaround that I can see is making lots of different XML files for each type of module I want to add, with respective classes, which just seems unnecessary and tedious.

    Sorry if there's a simple workaround that I can't see, or if this is the only way and I'm being lazy. But is there a way to specify certain brackets to get their content as described?
     
  2. Antistone

    Antistone

    Joined:
    Feb 22, 2014
    Posts:
    2,836
    I'm not familiar with the specific Xml decorations you're using, but XML in general is allowed to have heterogeneous content. I would guess you probably want something along these lines:

    Code (CSharp):
    1. [XmlRoot("moduledatabase")]
    2. public class ModulePuller {
    3.     [XmlArray("HullConfig")]
    4.     [XmlArrayItem("name")]
    5.     public List<Module> hullModules = new List<Module>();
    6.  
    7.     [XmlArray("EngineConfig")]
    8.     [XmlArrayItem("name")]
    9.     public List<Module> engineModules = new List<Module>();
    10. }
    If hulls and engines have different data fields (e.g. maybe hulls have "armor" and engines have "power"), then you'll probably want to define separate classes for them (possibly inheriting from a shared "Module" base class that includes shared fields like name and cost).
     
  3. csofranz

    csofranz

    Joined:
    Apr 29, 2017
    Posts:
    1,556
    Unless you are about to embark on a really complex project, I recommend you use JSON instead of XML. It's much more lightweight, has ready-to-use tools for reading and writing, and you can use standard List<> and (more importantly in your case) Dictionary<> variables.

    Is ther any reason you must use XML?
     
  4. Aquamarine222

    Aquamarine222

    Joined:
    Apr 21, 2019
    Posts:
    2
    Thanks AntiStone I'll try that
    Not really, it just seemed like the best format for a large database file
     
  5. Antistone

    Antistone

    Joined:
    Feb 22, 2014
    Posts:
    2,836
    JSON has very similar capabilities to XML but is smaller and IMO is easier to read or edit by hand. You should note that Unity's built-in JSON serializer isn't very robust, though.

    By the by, people will probably have an easier time understanding what you mean if you describe this as a "data file" rather than a "database". In software development, "database" usually has a more specialized meaning.