Click here to Skip to main content
Licence CPOL
First Posted 9 Sep 2008
Views 12,446
Bookmarked 15 times

Another XML parser in C#

By | 9 Sep 2008 | Article
A simple XML file reader

XmlParser.jpg

Download XmlParser.zip - 44.07 KB
Download XmlParserDll.zip - 6.76 KB

Introduction

Ok, so there's a bunch of parser out there. I haven't found one that does all the things I want it to do. Besides, I like to do it myself.

The solution contains two projects: XmlParser which does the actual work and XmlParserTest that is a demo application.

XmlParser provides the following features:

  • Load XML data from a XML file.
  • Load XML data from a text string.
  • Load XML data from a object of a class derived from TextReader.
  • The positions of where a tag starts and ends as well as where an element block starts and ends are stored together with the tags. By position I mean both the location in the file/string as well as the column/row of that position.

The class uses an event handler (XmlNodeEventHandler) that is called each time a start tag, end tag or text body is encountered. Beside regular tags it can handle the document start tag and comments.

Also included is an implementation of XmlParser, called XmlDocument. This class is aided by XmlDocumentLoader to do the actual loading.

XmlDocument provides the following features:

  • Manipulation of elements, attributes etc.
  • Save the XML data back to a file.
  • Return the contents as a string.

Using the code

If you don't want to fuzz with event handlers and so on, you can use the XmlDocument and XmlDocumentLoader classes instead. Together they will load the data and store it as a element tree. Here's some examples on how to do this:

// Load using a XML file as source.
// Note that the Load call has no parameters.
XmlParser.XmlDocument doc1 = new XmlParser.XmlDocumentLoader("SomeFile.xml").Load();
 
// Load using a text string as source.
// Note that the XmlDocumentLoad is constructed without parameters and that the
// text string is supplied to the Load call.
string s = "<Root>\n\r<Element Value=\"Hello\">Some text</Element>\n\r</Root>";
XmlParser.XmlDocument doc2 = new XmlParser.XmlDocumentLoader().Load(s);
 
// Extract the information of the single element (apart from the Root node of course) 
// in the text string.
string name = doc2.RootElement["Element"].Name;
string attr = doc2.RootElement["Element"].Attributes["Value"].Value;
string text = doc2.RootElement["Element"].Text;

If you want to have more control, you need to use XmlParser directly. The only thing to remember is to attach a handler for the XmlNode event. Here's an example on how to do that:

XmlParser.XmlParser p = new XmlParser.XmlParser(openFileDialog1.FileName);
p.XmlNode += new XmlParser.XmlNodeEventHandler(p_XmlNode);
p.Load();

The event handler might look something like this (outtake from the demo application):

private object p_XmlNode(object parent, XmlParser.XmlNodeEventArgs args)
{
  if (args.Type == XmlParser.XmlNodeType.ElementStart)
  {
    Node n = new Node();
    n.Name = n.Text = args.Name;
    n.Args = args.Attributes;
    n.Start = args.Start;
    n.End = n.BlockEnd = args.End;
 
    if (parent == null)
      Root = n;
    else
      ((Node)parent).Nodes.Add(n);
 
    return n;
  }
  else if (args.Type == XmlParser.XmlNodeType.ElementEnd)
  {
    ((Node)parent).BlockEnd = args.End;
  }
  else if (args.Type == XmlParser.XmlNodeType.Text)
  {
    string s = args.Text.Trim();
    if (parent != null && s.Length > 0)
      ((Node)parent).Data += s;
  }
  return null;
}

public class Node : TreeNode
{
  public string Name;
  public XmlParser.XmlAttributeCollection Args;
  public string Data = "";
  public XmlParser.XmlFilePos Start;
  public XmlParser.XmlFilePos End;
  public XmlParser.XmlFilePos BlockEnd;
}

The demo application shows how to use XmlParser to retreive the data and present it in a TreeView. When you select a node in the TreeView, its attributes are presented in the list box and the text in the text box.

Note that the object you create in the event handler is returned to the caller. This object is then included in the next call as the parent object. This means you don't have to keep track of where you are in the file. Of course, it's up to you to provide an object or just ignore this functionality and do it yourself.

The solution has been developed in .Net 1.1, so if you have a later version you might need to convert it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

Knasenmc

Software Developer

Sweden Sweden

Member

Have been programming since the early 80:s on various platforms (Commodore 64, ABC80, PDP-8, VAX, AS/400, PC) and languages (assembler, BASIC, Fortran, C, C++, Visual Basic, C#). C# is my preferred language at the moment.

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board. (secure sign-in)
 
Search this forum  
 FAQ
    Noise  Layout  Per page   
  Refresh
GeneralThe bad part of your script... PinmemberChuiby17:34 16 May '11  
GeneralThanks PinmemberMember 10616796:24 24 Jun '10  
GeneralGreat! Pinmemberidieh12:41 20 Nov '08  
Questionyou're kidding, right ? Pinmvptoxcct21:05 9 Sep '08  
AnswerRe: you're kidding, right ? Pinmemberjonnii5:21 10 Sep '08  
AnswerRe: you're kidding, right ? PinmemberKnasenmc4:26 12 Sep '08  

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

Permalink | Advertise | Privacy | Mobile
Web01 | 2.5.120517.1 | Last Updated 9 Sep 2008
Article Copyright 2008 by Knasenmc
Everything else Copyright © CodeProject, 1999-2012
Terms of Use
Layout: fixed | fluid