4

I am pretty new to using XML to define objects in C# I actually managed but there must be a better way.

the data for my game database is structured in several XML files of which this is one of the more elaborate as I use it for testing all over the place

<GameData xmlns:NSW="Napivo.StarWars">
<!-- Ships -->
<!-- AITroopAccelerator -->
<Asset Type="ShipDescription">
<Name>AITroopAccelerator</Name>
<Asset Type="SpriteAnimation">
  <Name>\Ships\AITroopAccelerator\1.png</Name>
  <Name>\Ships\AITroopAccelerator\2.png</Name>
  <Name>\Ships\AITroopAccelerator\3.png</Name>
  <Name>\Ships\AITroopAccelerator\2.png</Name>
  <Speed>150</Speed>
</Asset>

<Asset Type="WeaponGroup" Num ="0">
  <Weapon Name ="Missile" Angle ="0" X ="0" Y ="0"> </Weapon>

<Asset Type="WeaponGroup" Num ="1">
  <Weapon Name ="NegativeEnergyFlare" Angle ="180" X ="0" Y ="0"> </Weapon>
</Asset>
  <Weapon Name ="Lightning" Angle ="0" X ="0" Y ="0"> </Weapon>
</Asset>
<Asset Type="WeaponGroup" Num ="2">
  <Weapon Name ="FastLazer" Angle ="-10" X ="0" Y ="0"> </Weapon>
  <Weapon Name ="FastLazer" Angle ="+10" X ="0" Y ="0"> </Weapon>
  <Weapon Name ="Ion" Angle ="-90" X ="0" Y ="0"> </Weapon> 
</Asset>

<Asset Type="Armory">
  <Resource Type ="Energy" Ammout ="-1000" Recharge ="0.2"></Resource>
  <Resource Type ="Missile" Ammout ="-10" Recharge ="0"></Resource>
</Asset>

<HullStrength>100</HullStrength>
<ShieldStrength>100</ShieldStrength>


<ColorMask>\Ships\AITroopAccelerator\ColorMask.png</ColorMask>
<Scale>1</Scale>

And This is the code I need to write to make heads or tails of this xml file....

private void ReadShipDescription(XmlNode node)
    {
        ShipDescription sd = new ShipDescription();


        XmlNodeList NL = node.ChildNodes;

        foreach (XmlNode n in NL)
        {
            Console.WriteLine("{0} = {1}", n.Name, n.Value);

            if (n.Name == "Name")
            {
                sd.Name = n.InnerText;
            }

            if (n.Name == "Scale")
            {
                sd.Scale = float.Parse(n.InnerText);
            }

            if (n.Name == "HullStrength")
            {
                sd.HullStrength = float.Parse(n.InnerText);
            }

            if (n.Name == "ShieldStrength")
            {
                sd.ShieldStrength = float.Parse(n.InnerText);
            }

            if (n.Attributes != null)
            {
                foreach (XmlAttribute a in n.Attributes)
                {
                    if ((n.Name == "Asset") && (a.Name == "Type") && (a.Value == "SpriteAnimation"))
                    {
                        sd.HullAnimation = ReadSpriteAnimation(n);
                    }

                    if ((n.Name == "Asset") && (a.Name == "Type") && (a.Value == "WeaponGroup"))
                    {
                        sd.WeaponGroups.Add(ReadWeaponGroup(n));
                    }

                    if ((n.Name == "Asset") && (a.Name == "Type") && (a.Value == "Armory"))
                    {
                        XmlNode childnode = n.FirstChild;

                        while (childnode != null)
                        {
                            ResourceDescription rd = ReadResource(childnode);

                            if (rd.Ammount < 0)
                            {
                                rd.Ammount = float.PositiveInfinity;
                            }

                            sd.Armory.Add(rd);
                            childnode = childnode.NextSibling;
                        }
                    }

                    Console.WriteLine("{0} = {1}", a.Name, a.Value);
                }
            }

            if (n.Name == "ColorMask")
            {
                sd.ColorMask = n.InnerText;
            }
        }

        ShipDescriptions.Add(sd.Name, sd);
    }

That doesn't seem right to me.

Can anyone send me somewhere where I can learn how to read objects directly from XML into classes or structures?

Hope I don't get too many down votes for this one.

Thanks.

user2888973
  • 583
  • 3
  • 15

3 Answers3

5

You can use the xsd command to generate C# classes that match your XML:

xsd gamedata.xml   <- creates gamedata.xsd
xsd GameData.xsd /classes

(see Generate C# class from XML for more details)

And then deserialize the XML directly to a set of objects: http://msdn.microsoft.com/en-us/library/fa420a9y.aspx

Community
  • 1
  • 1
David Arno
  • 42,717
  • 16
  • 86
  • 131
  • In this case I'd like to accept both yours and Neel's answer as they both helped me. I chose this one as this is they way I will be going. Thank you for making me restructure all my XML files (Better now than later) :) – user2888973 Oct 21 '13 at 12:53
  • @user2888973, I have up-voted Neel's answer since you couldn't choose both. Glad to have been of help. – David Arno Oct 21 '13 at 12:55
2

For that just first load your xml file and do the operation u required..below is the link in which u can learn some part of it

http://www.dotnetcurry.com/ShowArticle.aspx?ID=564

Neel
  • 11,625
  • 3
  • 43
  • 61
1

Also you can deserialize XML into C# class and use that class in your code. Then, for example, you can write extension method .ToShipDescription() to get object of type ShipDescription.

IDeveloper
  • 1,249
  • 2
  • 13
  • 22