Search code examples
c#xmlxmlreader

How the XmlReader works in C#


I'm trying to read some Xml from a string I made, but really any Xml file would be ok.

I just want to browse the Xml nodes like it's a multidimensional matrix and eventually put them in a DataTable (to put them in a sql server with SqlBulkCopy). I've already looked in MSDN and around here. Could someone explain it plain and simple please?

This is the code:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Data;
using System.Xml;
using System.IO;

namespace ConsoleApplication2
{
    class Program
    {
        private static DataTable table = new DataTable();
        private static String xmlString =
        @"<?xml version='1.0'?>
        <!-- This is a sample XML document -->
        <Garage>
            <Car>
                <Name>Ferrari</Name>
                <Speed>360km/h</Speed>
                <Engine>Ferrari Enzo</Engine>
                <Color>Red</Color>
                <Year>1999</Year>
            </Car>
            <Car>
                <Name>Maserati</Name>
                <Speed>270km/h</Speed>
                <Color>Metal Grey</Color>
                <Year>2007</Year>
            </Car>
            <Car>
                <Name>Limo</Name>
                <Color>Black</Color>
                <Engine>Chevrolet</Engine>
                <Year>2007</Year>
            </Car>
        </Garage>";

        static void Main(string[] args)
        {
            Program x = new Program();
            XmlReader reader = XmlReader.Create(new StringReader(xmlString));
            while (reader.Read())
            {
                if (reader.NodeType == XmlNodeType.Element)
                {
                    Console.WriteLine(XmlNodeType.Element.ToString());
                    }
                }
            }

        }
    }

I would like to loop the whole thing and get something like:

Name: Ferrari Speed: 360km/h Engine: Ferrari Enzo

and so on, you got the drill.


Solution

  • System.Xml.Linq.XDocument.Parse(string) will give you an XDocument. XDocument.Root will get you the root XElement of your document. I think you'll find this very easy to work with.

    You're trying to use the previous generation of XML tools in .NET - the newer XDocument, XElement, etc tools are much more accessible.


    sample code

    using System.Xml.Linq;
    ...
    var root = XDocument.Parse(xmlString).Root;
    
    var cars = root
        .ToAll("Car")
        .Select(car => new
        {
            Name = car.ToFirst("Name").Value,
            Speed = car.ToAll("Speed").Any() ? car.ToFirst("Speed").Value : null,
            Color = car.ToFirst("Color").Value,
            Engine = car.ToFirst("Engine").Value,
            Year = int.Parse(car.ToFirst("Year").Value)
        })
        .ToList();
    

    helper class

    public static class XmlHelper
    {
        public static XNode ReadFrom(Stream stream)
        {
            using (var xmlReader = XmlReader.Create(stream))
                return XDocument.Load(xmlReader);
        }
    
        public static void WriteTo(Stream stream, XNode node)
        {
            using (var xmlWriter = XmlWriter.Create(stream))
                node.WriteTo(xmlWriter);
        }
    
        public static XElement ToFirst(this XElement ancestor, String descendantLocalName)
        {
            return ancestor.Descendants().FirstOrDefault(element => element.Name.LocalName == descendantLocalName);
        }
    
        public static IEnumerable<XElement> ToAll(this XElement ancestor, String descendantLocalName)
        {
            return ancestor.Descendants().Where(element => element.Name.LocalName == descendantLocalName);
        }
    
        public static string ToAttribute(this XElement element, string name)
        {
            var attribute = element.Attribute(XName.Get(name));
            return attribute != null ? attribute.Value : null;
        }
    }