[C#] Working with XML

Started by
5 comments, last by d000hg 14 years, 11 months ago
I'm having a problem finding good information on how to work with XML files in C#. Or at least I'm finding some pages but they all make it look like XmlDocument etc is no easier than using TinyXml in C++ - manually grabbing nodes and so on. Without moving to LINQ (I'd prefer to stay with .NET 3 since this is included on Vista) is this really as good as it gets? Maybe I'm spoilt after seeing how Flex has perfect XML integration but sure things have moved on since the bad old days of accessing XML through C++? Thanks...
Advertisement
One option is to use the XmlSerializer, which automatically maps objects and their referenced objects into an XML tree. This is good if the format of the XML document is under your control and you're okay with a format that still shows a bit that it's a serialized object model, not a consciously designed XML file.

If you need to parse arbitrary XML data, the XmlDocument isn't that bad, given that it supports XPath queries. For example, here's some code for parsing a simple XML file:

<skin>  <resources>    <font name="title" contentPath="gui/title-font" />    <bitmap name="cursors" contentPath="gui/cursors" />  </resources></skin>


/// <summary>Loads the resources contained in a skin document</summary>/// <param name="skinDocument">///   XML document containing a skin description whose resources will be loaded/// </param>private void loadResources(XmlDocument skinDocument) {  // Load the fonts specified in the skin  XmlNodeList fonts = skinDocument.SelectNodes("/skin/resources/font");  for(int index = 0; index < fonts.Count; ++index) {    string fontName = fonts[index].Attributes["name"].Value;    string contentPath = fonts[index].Attributes["contentPath"].Value;    SpriteFont spriteFont = this.contentManager.Load<SpriteFont>(contentPath);    this.fonts.Add(fontName, spriteFont);  }  // Load the bitmaps specified in the skin  XmlNodeList bitmaps = skinDocument.SelectNodes("/skin/resources/bitmap");  for(int index = 0; index < bitmaps.Count; ++index) {    string bitmapName = bitmaps[index].Attributes["name"].Value;    string contentPath = bitmaps[index].Attributes["contentPath"].Value;    Texture2D bitmap = this.contentManager.Load<Texture2D>(contentPath);    this.bitmaps.Add(bitmapName, bitmap);  }}


You still have to map between fields and XML attributes / nodes yourself, which one one side gives you more control but on the other side is a lot of code that could as well have been generated in most use cases.

However, I haven't done that much with XML, so maybe there's a much better way that I don't know about. Or maybe there's something in the Entity Framework or in NHibernate that could map your objects to XML structures (instead of a database).
Professional C++ and .NET developer trying to break into indie game development.
Follow my progress: http://blog.nuclex-games.com/ or Twitter - Topics: Ogre3D, Blender, game architecture tips & code snippets.
Quote:Original post by d000hg
I'm having a problem finding good information on how to work with XML files in C#. Or at least I'm finding some pages but they all make it look like XmlDocument etc is no easier than using TinyXml in C++ - manually grabbing nodes and so on.

Without moving to LINQ (I'd prefer to stay with .NET 3 since this is included on Vista) is this really as good as it gets? Maybe I'm spoilt after seeing how Flex has perfect XML integration but sure things have moved on since the bad old days of accessing XML through C++?

Thanks...


If you need manual access to XML the only solution is accessing manually nodes or using LINQ.
I don't know what you mean by "easy as using tinyxml in c++", but I found using it rather easy to use. (i mean the XMLDocument class)
If you just need serialization and deserialization there are classes that permits easy and fast usage (just one call and everything is ok) like XmlSerializer.
Just to give you an other option to consider...

If you you are not tied to using XML then maybe you could consider JSON, especially if it is for serialization of runtime objects. It hasn't got the flexibility of XML for self description but it is very lightweight and .NET 3.0 should have everything you need.

Below is some code from my current project, its a web app but there is no reason why JSON couldn't be used for a normal Win app as well.

[source language="C#"]using System.Runtime.Serialization;using System.Runtime.Serialization.JSON;    /// <summary>    /// DATA_CONTRACT    /// CLASS: LobbyMessageJSONContract    /// </summary>    [DataContract]    class LobbyMessageJSONContract    {        [DataMember]        internal string MemberID;        [DataMember]        internal string MessageText;        [DataMember]        internal string TimeStamp;        public LobbyMessageJSON(string memberID, string text, string timeStamp)        {            MemberID = memberID;            MessageText = text;            TimeStamp = timeStamp;        }    }    /// <summary>    /// DATA_CONTRACT    /// CLASS: MessageArrayJSONContract    /// </summary>    [DataContract]    class MessageArrayJSONContract    {        [DataMember]        internal LobbyMessageJSON[] Messages;        public MessageArrayJSONContract(LobbyMessageJSON[] messages)        {            Messages = messages;        }    }    class Serialize    {        public string GetJSONMessageArray(LobbyMessagesJSONContract[] messages)        {            MessageArrayJSONContract msgArray = new MessageArrayJSONContract(messages);            DataContractJsonSerializer serialize = new DataContractJsonSerializer(typeof(MessageArrayJSONContract));            MemoryStream memStream = new MemoryStream();            serialize.WriteObject(memStream, msgArray);            return StaticStreamHelpers.GetStringFromMemoryStream(memStream);        }    }


It's always nice to have options :)

The code above might have errors, as I had to change a few things to keep it concise, but you should get the idea.
Innovation not reiterationIf at any point I look as if I know what I'm doing don't worry it was probably an accident.
Quote:Original post by Cygon
If you need to parse arbitrary XML data, the XmlDocument isn't that bad, given that it supports XPath queries. For example, here's some code for parsing a simple XML file:

<skin>  <resources>    <font name="title" contentPath="gui/title-font" />    <bitmap name="cursors" contentPath="gui/cursors" />  </resources></skin>


*** Source Snippet Removed ***
That's really helpful, I hadn't see the SelectNodes method... I was thinking I had to manually iterate all nodes looking for ones with the right names... thanks!


feal87: it's not hard but XML read/write code is about the most boring thing to code.
.NET 3.5 introduces System.Xml.Linq.XDocument, which is basically LINQ to XML.
Mike Popoloski | Journal | SlimDX
Quote:Original post by Mike.Popoloski
.NET 3.5 introduces System.Xml.Linq.XDocument, which is basically LINQ to XML.
Now go read my post again [wink]

This topic is closed to new replies.

Advertisement