## Recommended Posts

GameMasterXL    100
I have searched everywere and havn't found much good info on this. Is what i am wanting to do is read in a xml file that will store how my program looks like the background colour, font colour, font size, font type, font style ect ect so then i could change the programs looks with xml. This is what a basic xml file for my program would look like:
<buttons>
<bgcolor>red</bgcolor>
<fontcolor>blue</fontcolor>
<fontsize>12</fontsize>
<fonttype>arial</fonttype>
<fontstyle>bold</fontstyle>
</buttons>


How would i read this in so i can get each individual value to change my programs properties and be able to allways expand on the xml file aswell? thanks in advance. [/source]

##### Share on other sites
Dave Hunt    4872
There are a ton of XML-with-C# articles here.

##### Share on other sites
joanusdmentia    1060
In .NET 1.1 you want the XmlSerializer class. Things have apparently changed a bit for .NET 2.0 though, but I haven't had a chance to check out XML serialization in 2.0 yet.

##### Share on other sites
GameMasterXL    100
Quote:
 Original post by Dave HuntThere are a ton of XML-with-C# articles here.

I did find one usefull there but it only seemed to read in all commands like this
<width> .. </width>
<height> .. </height>

and i don't think i can encapsulate the attributes into each object like in my xml setup file i want to be able to change buttons ui, textboxs, window, font ect and each one of those are in its own catogary with its own attributes like
<buttons>
<width>123</width>
</buttons>

I will also look into serialization to but i suck at xml lol.

##### Share on other sites
Dave Hunt    4872
You might try a format more like this:
<buttons> <property name="bgcolor" value="red" /> <property name="fontcolor" value="blue /> <property name="fontsize" value="12" /> <property name="fonttype" value="arial" /> <property name="fontstyle" value="bold" /></buttons>

I find that a bit easier to parse.

##### Share on other sites
GameMasterXL    100
How do i parse that with C# xml classes? so i can read in the values of each attribute and assigne the value into my programs global variables.

##### Share on other sites
Rob Loach    1504
You have a couple of options when it comes to XML in .NET:

• The System.Xml namespace provides a XmlDocument which you can use to construct and "destruct" XML documents. You pretty much just write it node by node or read through it node by node.
• The IXmlSerializable interface will let you serialize classes by reading and writing the members your own way.
• With the XmlSerializer class, you can serialize classes to xml dynamically.

Play around with each method of creating and reading XML data and pick which method you like best. It really depends on what you're trying to accomplish with what you're doing.

##### Share on other sites
GameMasterXL    100
Is what i am creating is a setup file so i can read the xml data in and each element has attributes then i read each attribute in and assigne the value of each into the right variable. How can i do this can you by anychance show some code? thanks.

##### Share on other sites
xycos    146
Here's some code from my game. Obviously, it has nothing to do with whatever you're doing, but you might be able to gleam something from it.

    public static void loadShipsXml() {        SHIPS = new Dictionary<string, ShipData>();        XmlDocument doc = new XmlDocument();        doc.Load(Settings.DATA_PATH + @"ships.xml");        XmlNode rootNode = doc.DocumentElement;        XmlNodeList allShips = rootNode.ChildNodes;        for(int i = 0; i < allShips.Count; i++) {            ShipData nextShip = new ShipData();            XmlElement current = (XmlElement) allShips[i];            XmlNodeList children = current.ChildNodes;            for(int j = 0; j < children.Count; j++) {                if(children[j].Name == "speed") {                    nextShip.speed = double.Parse(children[j].InnerText);                } else if(children[j].Name == "hp") {                    nextShip.hp = int.Parse(children[j].InnerText);                } else if(children[j].Name == "graphics") {                    nextShip.graphics = Settings.processXMLGraphics(children[j]);                } else if(children[j].Name == "component") {                    nextShip.components.AddLast(ComponentData.COMPONENTS[children[j].InnerText]);                }            }            SHIPS.Add(current.Attributes[0].Value, nextShip);        }

##### Share on other sites
SnprBoB86    277
Side note:

C# allows switches on strings:

               if(children[j].Name == "speed") {                    nextShip.speed = double.Parse(children[j].InnerText);                } else if(children[j].Name == "hp") {                    nextShip.hp = int.Parse(children[j].InnerText);                } else if(children[j].Name == "graphics") {                    nextShip.graphics = Settings.processXMLGraphics(children[j]);                } else if(children[j].Name == "component") {                    nextShip.components.AddLast(ComponentData.COMPONENTS[children[j].InnerText]);                }

can become:

               switch (children[j].Name)             {               case "speed":                    nextShip.speed = double.Parse(children[j].InnerText);                    break;                case "hp":                    nextShip.hp = int.Parse(children[j].InnerText);                    break;                case "graphics"                    nextShip.graphics = Settings.processXMLGraphics(children[j]);                    break;                case "component":                    nextShip.components.AddLast(ComponentData.COMPONENTS[children[j].InnerText]);                    break;                }

##### Share on other sites
xycos    146
I know XD. I just have always found switch statements ugly -_____-. But thanks!

##### Share on other sites
joanusdmentia    1060
IMHO serialization will be the simplest approach for this.

using System.Drawing;using System.Xml.Serialization;[Serializable]class Buttons{    public KnownColor BgColor;    public KnownColor FontColor;    public int FontSize;    public string FontName;    public FontStyle FontStyle;    public static Buttons Load(Stream stream)    {        XmlSerializer serializer = new XmlSerializer(typeof(Buttons));        return (Buttons)serializer.Deserialize(stream);    }}

A whooping 2 lines of code to load your settings from an already open stream. KnownColor is an enumeration of known color names, if you don't want this you can just use a string instead. Similarly for Fontstyle.

See here for info on attributes that let you do all sorts of stuff (change the name of nodes so that they don't have to match the variable names, use XML attributes instead of nodes, etc.).

##### Share on other sites
GameMasterXL    100
It seems though that the serializer just writes data out. This is what i am wanting to parse this type of data and the way it is layed out can change.

<buttons> <property: name="bgcolor" value="red"/> <property: name="bdcolor" value="blue"/> <property: name="font" value="arial"/> <property: name="fontcolor" value="white"/></buttons><mainapp> <property: name="appico" value="default.ico"/> <property: name="bgcolor" value="darkblue"/></mainapp>

So it would contain attributes like the above, i am a bit confused still on how i would parse this in so i can get all the data from each attribute and store it into variables? sorry about the questions i am new at C#.

##### Share on other sites
Vexorian    152
With xml it is sometimes a matter of style, I would go with :
<buttons bgcolor="red" bdcolor="blue" font="arial" fontcolor="white"/><mainapp appico="default.ico" bgcolor="darkblue"/>

I do things like that myself as much as possible, I kind of dislike to have elements if they only have content and don't have child elements, then I preffer them as attributes as long as the values are to be expected

feeling: This is the kind of format that works better with ini, ouch

[Edited by - Vexorian on November 13, 2005 3:31:05 PM]

##### Share on other sites
GameMasterXL    100
So the above format you showed looks better?

How would i parse this in C#?

##### Share on other sites
dalleboy    324
Input test.xml:
<buttons> <bgcolor>red</bgcolor> <fontcolor>blue</fontcolor> <fontsize>12</fontsize> <fonttype>arial</fonttype> <fontstyle>bold</fontstyle></buttons>

Program using XPath:
using System;using System.Xml.XPath;class Program{   static void Main()   {      XPathDocument doc = new XPathDocument(@"test.xml");      XPathNavigator nav = doc.CreateNavigator();      Console.WriteLine(nav.SelectSingleNode(@"//bgcolor").Value);      Console.WriteLine(nav.SelectSingleNode(@"//fontcolor").Value);      Console.WriteLine(nav.SelectSingleNode(@"//fontsize").ValueAsInt);      Console.WriteLine(nav.SelectSingleNode(@"//fonttype").Value);      Console.WriteLine(nav.SelectSingleNode(@"//fontstyle").Value);   }}

Output:
redblue12arialbold

Learn XPath

Disclaimer: The above XPath strings sent to SelectSingleNode are probably not 100% correct, I do not know XPath.

##### Share on other sites
joanusdmentia    1060
Quote:
 Original post by GameMasterXLIt seems though that the serializer just writes data out. This is what i am wanting to parse this type of data and the way it is layed out can change.So it would contain attributes like the above, i am a bit confused still on how i would parse this in so i can get all the data from each attribute and store it into variables? sorry about the questions i am new at C#.

Did you even look at the link I provided? The serializer both serializes (writes) and deserializes (read). Here's an example that will parse your desired structure (ignoring the ':', I'm not sure if that's valid since it's used to specify the namespace).

using System.Drawing;using System.Xml.Serialization;[Serializable]class Property{    [XmlAttribute("name")]  public string Name;    [XmlAttribute("value")] public string Value;}[Serializable][XmlRoot("rootnodename")]class Settings{    [XmlArray("buttons")]    [XmlArrayItem("property")]    public Property[] Buttons;    [XmlArray("mainapp")]    [XmlArrayItem("property")]    public Property[] MainApp;    public static Settings Load(Stream stream)    {        XmlSerializer serializer = new XmlSerializer(typeof(Settings));        return (Settings)serializer.Deserialize(stream);    }}

As you can see, the code for loading the settings is exactly the same (apart from the different type being loaded), the way in which the data is structured is control by A) the structure of your types and B) the attributes you apply to their members. If you want to use a Hashtable so that you can index properties by their name things start to get more complicated and a different approach may prove to be easier.

##### Share on other sites
GameMasterXL    100
How would i store them values from the deserializer into my variables? also xpath looks promasing.

##### Share on other sites
Krisc    494
You should also use String.Equals() instead of == for strings.

Quote:
 Original post by SnprBoB86Side note:C# allows switches on strings:*** Source Snippet Removed ***can become:*** Source Snippet Removed ***

##### Share on other sites
Arild Fines    968
Quote:
 Original post by KriscYou should also use String.Equals() instead of == for strings.

No point. operator== for String is the same as .Equals.

##### Share on other sites
Rob Loach    1504
I was working with unmanaged code for one project and needed a way to customize getting and setting the XML elements so that I had full control over the conversion. So I started up a new project and did some tests and came up with a new class named XmlDictionary.

It's pretty much a Hashtable (string-value pairs) that can be saved and loaded as XML. You can store any primitive datatype in it as well as any user class you make that implements IXmlDictionaryElement.

// Save some information as XMLXmlDictionary data = new XmlDictionary("data.xml");data["Width"] = 640;data["Height"] = 480;data["Title"] = "Hello World!";data.Save();// Load the data from the diskXmlDictionary loadedData = new XmlDictionary();loadedData.Load("data.xml");// Display some data from it...System.Console.WriteLine( loadedData["Title"] );System.Console.WriteLine("Width: " + loadedData["Width"] );System.Console.WriteLine("Height: " + loadedData["Height"] );

##### Share on other sites
GameMasterXL    100
Hmm interesting thnx.