The example below uses the LINQ to XML predecessor System.Xml.XmlDocument simply because I still prefer the regex parsing method. It can easily be adapted to use XDocument instead based on your preference. The end resulting output (IEnumerable) is the same.
code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Dynamic;
using System.Xml.Linq;
namespace AIS.Common
{
public class DocParser : IDisposable
{
public enum DocTypes
{
Xml
};
private XmlDocument Document { get; set; }
//private XDocument Document { get; set; }
private DocTypes DocType { get; set; }
//constructor
/// <summary>
///
/// </summary>
/// <param name="dt">type of document, currently only supports xml</param>
/// <param name="f">filename and path</param>
public DocParser(DocTypes dt, string fp)
{
try
{
switch (dt)
{
case DocTypes.Xml:
DocType = DocTypes.Xml;
Document = new XmlDocument();
Document.Load(fp);
//Document = XDocument.Load(fp);
break;
default:
throw new Exception("Constructor::invalid or unknown doc type specified");
}
}
catch (Exception ex)
{
throw new Exception("Constructor::Error with document load or doc type.",ex);
}
}
public IEnumerable<dynamic> GetElements(string regex)
{
return XmlToExpandoObject(regex);
}
private IEnumerable<dynamic> XmlToExpandoObject(string regex)
{
dynamic eo = new ExpandoObject();
var dictionary = eo as IDictionary<string, object>;
XmlNodeList xnl = Document.SelectNodes(regex);
foreach (XmlNode xn in xnl)
{
foreach (XmlAttribute xa in xn.Attributes)
{
dictionary[xa.Name.ToString()] = xa.Value.Trim();
//TrySetAttr(xn.LocalName, xn);
}
yield return eo;
}
}
}
}
sample xml:
<?xml version="1.0" encoding="utf-8" ?> <robots> <robot id="1" age="5" /> <robot id="2" age="3" /> </people>
usage:
DocParser dp = new DocParser(DocParser.DocTypes.Xml, Server.MapPath("~/xmlfilename.xml")); //can also retrieve xml from external service, etc
var robots = dp.GetElements("*/robot");
foreach (var r in robots) {
Console.WriteLine("Robot id={0}, age={1}", r.id,r.age); //output. if this is web app you will likely do this differently
}
References
http://msdn.microsoft.com/en-us/magazine/ff796227.aspx
Leave a comment