
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:
XmlParser.XmlDocument doc1 = new XmlParser.XmlDocumentLoader("SomeFile.xml").Load();
string s = "<Root>\n\r<Element Value=\"Hello\">Some text</Element>\n\r</Root>";
XmlParser.XmlDocument doc2 = new XmlParser.XmlDocumentLoader().Load(s);
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.