thinkmmk
thinkmmk

Reputation: 487

Convert embedded XML to List<T> within a Repository

I have a situation where in I have to read my master data from XML files. Hence I have created a Repository which looks like this.

public class XmlReadRepository<T> : IReadRepository<T> where T : class, new()
{
    private IEnumerable<T> _data { get; set; }
    private IQueryable<T> _query { get; set; }

    public XmlReadRepository()
    {
        Type t = typeof(T);
        //Load _data from xml
    }

    public IQueryable<T> All()
    {
        return _query;
    }

    public IQueryable<T> Get(System.Linq.Expressions.Expression<Func<T, bool>> filter = null, Func<IQueryable<T>, IOrderedQueryable<T>> orderBy = null, string includeProperties = "")
    {
        throw new NotImplementedException();
    }        
}

I have exported all my SQL database data into XML file using below SQL query

  SELECT *
FROM Company
FOR XML RAW, ROOT('Company')

Whose outputs comes as below

<Company>
  <row Id="1" Name="ABC" StartDate="2000-03-01" />
  <row Id="2" Name="XYZ" StartDate="2001-13-11" />
</Company>

The xml is physically saved to a file and is embedded as a resource.

Now I am looking for some fast way to serialize the xml data into list. I have tried loading the xml file with stream and then using reflection created objects by iterating through the XML. Is there any better way by which I can serialize the xml data to my C# object.

Also please share your inputs on whether is it good to have xml as an embedded resource as the size of each xml can be around 8MB and there are 5 such XMLs.

Upvotes: 0

Views: 134

Answers (2)

jdweng
jdweng

Reputation: 34421

You can turn my code into a function

   public class Row
    {
        private static XmlTextReader reader = null;
        public int Id { get; set; }
        public string name { get; set; }
        public DateTime startDate { get; set; }

        public Row() { }

        public Row(TextReader sReader)
        {
            reader = new XmlTextReader(sReader); //can be filename instead of stringreader
        }
        public Row Get(string elementName)
        {
            Row results = null;
            if (!reader.EOF)
            {
                if (reader.Name != elementName)
                {
                    reader.ReadToFollowing(elementName);
                }
                if (!reader.EOF)
                {
                    XElement newRow = (XElement)XElement.ReadFrom(reader);
                    results = new Row() { Id = (int)newRow.Attribute("Id"), name = (string)newRow.Attribute("Name"), startDate = (DateTime)newRow.Attribute("StartDate") };
                }
            }
            return results;
        }

    }​

Upvotes: 1

jdweng
jdweng

Reputation: 34421

Use xml linq like below

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;
using System.IO;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            string xml =
                "<Company>" +
                  "<row Id=\"1\" Name=\"ABC\" StartDate=\"2000-03-01\" />" +
                  "<row Id=\"2\" Name=\"XYZ\" StartDate=\"2001-13-11\" />" +
                "</Company>";

            XDocument doc = XDocument.Parse(xml);   // use Load to read from file

            var rows = doc.Descendants("row").Select(x => new
            {
                id = (int)x.Attribute("Id"),
                name = (string)x.Attribute("Name"),
                startDate = (DateTime)x.Attribute("StartDate")
            }).ToList();

            //using xmltextreader
            List<Row> rows2 = new List<Row>();
            StringReader sReader = new StringReader(xml);
            XmlTextReader reader = new XmlTextReader(sReader); //can be filename instead of stringreader
            while(!reader.EOF)
            {
                if (reader.Name != "row")
                {
                    reader.ReadToFollowing("row");
                }
                if (!reader.EOF)
                {
                    XElement newRow = (XElement)XElement.ReadFrom(reader);
                    rows2.Add(new Row() { Id = (int)newRow.Attribute("Id"), name = (string)newRow.Attribute("Name"), startDate = (DateTime)newRow.Attribute("StartDate") });
                }
            }

        }
    }
    public class Row
    {
        public int Id { get; set; }
        public string name { get; set; }
        public DateTime startDate { get; set; }

    }

}
​

Upvotes: 0

Related Questions