RunUO Community

This is a sample guest message. Register a free account today to become a member! Once signed in, you'll be able to participate on this site by adding your own topics and posts, as well as connect with other members through your own private inbox!

Xml Tutorial for .Net

mordero

Knight
Xml Tutorial for .Net

Xml Tutorial

This tutorial is for people who understand the basics of Xml, what it is, how it works, etc. If you do not know what Xml, I would advise looking at the following websites:
  1. Brief overview of XML (history, features, syntax) from Wikipedia: http://en.wikipedia.org/wiki/XML
  2. Some quick tutorials for XML from W3Schools: http://www.w3schools.com/xml/default.asp
  3. Some quick tutorials for XPath (the way to navigate through an Xml file) from W3Schools: http://www.w3schools.com/xpath/default.asp
Now that you know a bit about what Xml is, I just want to point out, that the .Net framework offers many different methods of working with Xml files and that I am just showing what I believe to be the easiest methods. If anything I demonstrate is wrong or you believe could be fine tuned, please let me know so I can fix it :).

I created a sample program for most of what I show in this tutorial so you can see it in action. I believe that the comments should help explain everything I do, but if you have any questions, again, please ask. However, please limit the questions to stuff actually relating to Xml and not the actual program (unless you find a bug or some such). In some cases, I will refer to this program without saying much in the tutorial because I believe that looking at the code would be more benefit that what I say.

Demo source code: (Requires .Net 2.0)
http://www.runuo.com/forums/attachment.php?attachmentid=10808&stc=1&d=1171183351

Introduction
Some quick notes before I start:
  • I use XmlDocument for everything when it comes to reading, writing, creating, etc an Xml file. I find this the easiest method of working with Xml files.
  • Although my code does not demonstrate it very well, there is a difference between XmlNode and XmlElement. An XmlNode is pretty everything that you can add into an Xml file (almost every object used is based off of XmlNode), while a XmlElement is a set of tags and the text inside of them. *Yeah not very technical, but oh well*
Also, the following should be at the top of any script that makes use of any of the Xml namespace:
Code:
using System.Xml;

and assume the following is already included in any examples shown (unless otherwise stated):
Code:
XmlDocument doc = new XmlDocument();
doc.Load("People.xml");

Also note that when working with Xml, everything is case sensitive so "People" is NOT the same as "people".

What's covered in this tutorial
  1. Iterating through an Xml file
  2. Using XmlNodes and Reading Values from an Xml File
  3. Writing to an Xml file
  4. Creating an Xml file
Iterating through an Xml File

Usually if you do not know the layout of an Xml file before reading it, there is nothing very useful you can pull from it. Despite this, I thought it would be cool to show an example of showing a tree view of any xml file you open. This should work with almost every Xml file that you try to read with it, but I'm not going to guarantee it. Once you get a handle on whats going on with it though, it might be help to you in the future :).

Using XmlNodes and Reading Values from an Xml File

Pretty much everything in an Xml document can be referred to as a node. When working with Xml files, you need to have a way to choose the specific node you want. Doing so in C# is extremely easy.

First, I want to show a simple Xml file and show how you would refer to each one by its XPath.

This is the basic layout of the Xml file I use in the demo. It's root element is "People" and contains a Person that has a message attribute, with a Name, Country, Age, and Gender child elements.

(This is the contents of People.xml)
Code:
<?xml version="1.0" encoding="utf-8"?>
<People>
     <Person message="Hello">
          <Name>Eric</Name>
          <Country>USA</Country>
          <Age>20</Age>
          <Gender>Male</Gender>
     </Person>
     <Person>
          <Name>Kyle</Name>
          <Country>USA</Country>
          <Age>19</Age>
          <Gender>Male</Gender>
     </Person>
</People>

Lets say you wanted retrieve the first person. Its XPath would be "People/Person", its name would be "People/Person/Name", its age would be "People/Person/Age", etc.

When working with Xml in C#.Net, its extremely easy to use XPaths to choose which nodes to select. You can select either a collection of all the nodes that share that XPath or the first one that uses it. The following examples will demonstrate this:

This one will create an XmlNodeList that contains all of the Person elements and loops through them:
Code:
 XmlNodeList nodeList = doc.SelectNodes("People/Person");
foreach(XmlNode node in nodeList)
{
     //do stuff
}

You can also choose an individual XmlNode from the XmlNodeList by the following:
Code:
XmlNodeList nodeList = doc.SelectNodes("People/Person");
XmlNode node = nodeList.Item(1);//is the second XmlNode in the XmlNodeList

If you only wanted to select the first occurance of the Person element, you could also load it from the XmlDocument as well:
Code:
XmlNode node = doc.SelectSingleNode("People/Person");

Once we have the Person element in a node, we can use that node to select new elements beneath it (also called ChildNodes, which would include its Name, Country, Age, and Gender) as well as any attributes that it or its children have.

This example would retrieve the child nodes along with its attribute "message":
Code:
XmlNode PersonNode = doc.SelectSingleNode("People/Person");
 
//lets load all those children
XmlNode NameNode = PersonNode.SelectSingleNode("Name");
XmlNode AgeNode = PersonNode.SelectSingleNode("Age");
XmlNode CountryNode = PersonNode.SelectSingleNode("Country");
XmlNode GenderNode = PersonNode.SelectSingleNode("Gender");
 
//load the message attribute
XmlAttribute MessageAttribute = PersonNode.Attributes["message"];//this could also be done with PersonNode.Attributes[0]

Continuing from this previous example, if we wanted to get the string values from these elements we would do something like this:
Code:
string Name = NameNode.InnerText;//i used InnerText here instead of Value for XmlNodes because I have weird results (ie returning null) when trying to use Value, any help would be great! :)
string Country = CountryNode.InnerText;
string Message = MessageAttribute.Value;

However, for integers and enums its a bit different cause you need to convert the strings to the correct types:
Code:
public enum Gender
{
     Male, 
     Female, 
     Undefined//used in case the correct one cannot be found
}
 
//for enums
Gender gender;
switch(GenderNode.InnerText)
{
     case "Male":
          gender = Gender.Male;
          break;
     case "Female":
          gender = Gender.Female;
          break;
     default:
          gender = Gender.Undefined;
          break;
}
 
//for integers
int Age;
if (!int.TryParse(AgeNode.InnerText, out Age)
{
     Age = 0;
}

Notice though that I never checked to see if these nodes actually existed before I tried to pull values from them, you would do that like this:
Code:
if (NameNode != null)
{
     //get value from it
}

or

Code:
try
{
     //get value from Node
}
catch
{
     //variable to some default value
}


That's all there is when reading values from an Xml file. Of course, like I stated before, there are other methods to do this, but I find this to be the easiest way.


Writing to an Xml file

Writing to an Xml file is extremely easy, you can append new elements or nodes or change values of nodes currently in the file with the same ease as reading the file.

To change the values of current nodes, all you must do is load the XmlNode like you did when reading it:
Code:
XmlNode PersonNode = doc.SelectSingleNode("People/Person");

and then change the values in it, for sake of simplicity (and to not repeat myself since it is in the demo), I will only change the value of the message attribute here
Code:
//change the value
PersonNode.Attributes["message"].Value = "new value";
 
//save the document
doc.Save("People.xml");

Simple, eh?

In order to create a new node, you just need to create a new instance of an XmlNode, make your changed and then append/prepend/etc it to whatever node you want to be its parent.

In this example, I will create a new Person element and append it to the root element. However, this one will only contain the person's name and the attribute since it is demonstrated in the demo to a fuller extent.
Code:
XmlNode PersonNode = doc.CreateNode(XmlNodeType.Element, "Person", "");
 
XmlNode NameNode = doc.CreateNode(XmlNodeType.Element, "Name", "");//create the new node
NameNode.InnerText = "Bill"; //set its value
PersonNode.AppendChild(NameNode); //add it to its parent, which is the Person
 
XmlAttribute MessageAttribute = doc.CreateAttribute("message");
MessageAttribute.Value = "Hahaha"; //set the value of the attribute
PersonNode.Attributes.Append(MessageAttribute); //add it to the Person element
 
doc.DocumentElement.AppendChild(PersonNode); //DocumentElement is the root element and the parent of Person
//save the file
doc.Save("People.xml");

And thats it, not too difficult was it?

If you are making massive changes to a Xml file, you shouldnt save after everytime you make a change, but when you are finished working with the file. This way you decrease the number of times you have to write to the harddrive, which can be a drag on your script/program.

Creating an Xml File

What if you dont have an Xml file created yet and you want to generate one on the fly? Fortunately for us, its almost identical to adding a node to an existing xml file. The only difference is you need to create an Xml Declaration node and a root node. Since it isnt much different, I'll let you look at it in the demo :).


Conclusions

Well thats about it when it comes to Xml files and working with them in C# and the .Net framework. Hopefully I covered enough to give you a foot in the door and start you working towards a great way of storing data :). Good luck!! And if you have any questions or corrections to me or for this tutorials, please contact me!!!!
 

Attachments

  • XmlDemo.zip
    140.4 KB · Views: 91

mordero

Knight
Part 2
Since I have been working with XML a lot more recently, I figured I would give examples of some of the other ways to work with XML with which some people could potentially find easier to work. I know in different cases, these methods mean less code to write and easier understanding of what exactly is going on.

However, I'm still working on this tutorial, so its coming soon... :)
 
Top