-4

I have a xml file e.g. like this:

<?xml version="1.0" encoding="UTF-8"?>

    <Request>
        <Authenticate>
            <Username>Username</Username>
            <Token>Token</Token>
        </Authenticate>
        <Fields>
            <Group name="test">
                <Field>
                    <Name>Field 1</Name>
                    <Type>string</Type>
                </Field>
                <Field>
                    <Name>Field 2</Name>
                    <Type>string</Type>
                </Field>
            </Group>
            <Group name="Group 2">
                <Field>
                    <Name>Field 3</Name>
                    <Type>string</Type>
                </Field>
                <Field>
                    <Name>Field 4</Name>
                    <Type>string</Type>
                </Field>
            </Group>
        </Fields>
    </Request>

And I want to parse this in C#.Net I think I can do this like this:

XmlReader reader = XmlReader.Create(FilePath);
while(reader.Read()) {}

But how can I access the nodes? And also the name of the group? <Group name="Group 2"> Can anyone help me? Thanks

cherrycoding
  • 1,855
  • 2
  • 14
  • 19
  • 2
    http://msdn.microsoft.com/en-us/library/cc189056(v=vs.95).aspx – Ant P Dec 29 '13 at 15:03
  • possible duplicate of [How does one parse XML files?](http://stackoverflow.com/questions/55828/how-does-one-parse-xml-files) – Louis Jan 23 '14 at 23:57

4 Answers4

5

And another alternative using xml serialization

XmlSerializer ser = new XmlSerializer(typeof(SO.Request));
using(var f = File.Open(filename,FileMode.Open))
{
    var requests = (SO.Request)ser.Deserialize(f);
}

public class SO
{
    public class Request
    {
        public Authenticate Authenticate { get; set; }
        public List<Group> Fields { get; set; }
    }

    public class Authenticate
    {
        public string Username { get; set; }
        public string Token { get; set; }
    }

    public class Group
    {
        [XmlAttribute("name")]
        public string Name { get; set; }
        [XmlElement("Field")]
        public List<Field> Fields { get; set; }
    }

    public class Field
    {
        public string Name { get; set; }
        public string Type { get; set; }
    }
}
L.B
  • 114,136
  • 19
  • 178
  • 224
3

An XmlReader gives you the possibility to parse the XML without loading it in-memory. This is very good for large XML files. For example if you wanted to get all name attributes of the Groups you could do this:

using (var reader = XmlReader.Create("test.xml"))
{
    while (reader.Read())
    {
        if (reader.IsStartElement() && reader.Name == "Group")
        {
            // we are inside the Group element. We can now read its attributes
            string name = reader.GetAttribute("name");
            Console.WriteLine(name);
        }
    }
}

If on the other hand your XML is not that large you could load it into an XDocument which provides a more convenient way to perform XPath queries and retrieve the desired information:

var doc = XDocument.Load("test.xml");
var groups = doc.XPathSelectElements("/Request/Fields/Group");
foreach (var group in groups)
{
    Console.WriteLine(group.Attribute("name").Value);
}
Darin Dimitrov
  • 1,023,142
  • 271
  • 3,287
  • 2,928
  • I've tested the xmlreader and it works, but how can I loop trough the nodes? E.g. if I am inside the group I want loop the fields. – cherrycoding Dec 29 '13 at 15:19
  • The same way I did for the `Group` node: `if (reader.Name == "Field") { ... you are inside the Field node ... }`. And so on. – Darin Dimitrov Dec 29 '13 at 15:20
  • With [code]if(reader.Name == "Field")[/code] it doesn't work, I think the name is still Group, I think I have to move to the Element? And the Group Node can contain many Field attributes, so I need a loop, also for group, because the xml can contain many Groups. – cherrycoding Dec 29 '13 at 15:32
  • You should not nest the `if (reader.Name == "Field")` inside the if for the Group. It should be a separate statement. You should realize that if you decide to use an XmlReader you need to keep track (with temporary variables) which nodes you are inside. Use a combination of `reader.IsStartElement()` and `reader.Name` to determine where precisely you are currently in the XML document. – Darin Dimitrov Dec 29 '13 at 15:33
1

Using LINQ2XML

or XMLDocument

or the XPath routines

or, if you want to be fancy, using XMLSerialiser to turn it into an object.

If you still want to use XMLReader, you just put calls inside your while loop to check each element. Use GetElement or GetAttribute to get the relevant parts of each item in the XML document. eg:

if ((xmlReader.NodeType == XmlNodeType.Element) && (xmlReader.Name == "Group"))
  if (xmlReader.HasAttributes)
    name = xmlReader.GetAttribute("name");
gbjbaanb
  • 51,617
  • 12
  • 104
  • 148
1

You can achieve to this by using System.Xml.Linq.XDocument. it's more easy and comfortable to use:

string strXml = File.ReadAllText(xFilePath);
XDocument xd = XDocument.Parse(strXml);
var xNode = xd.Element("Request").Element("Fields").Elements("Group").FirstOrDefault(e => e.Attribute("name").Value == "Group 2");
Mohamed Salemyan
  • 691
  • 2
  • 15
  • 31
  • Yeah I just tried Linq2XML is really more easy, but I have still problems. Here's my code: `code` XDocument doc = XDocument.Load(fileName); foreach (XElement el in doc.Root.Elements()) { foreach (XElement field in el.Elements()) { foreach (XElement group in field.Elements()) { output = group.Attribute("name").Value; } } }`code` I've done it with foreach to make it more easy. – cherrycoding Dec 29 '13 at 16:11
  • 1
    You don't specified witch element you want to return. – Mohamed Salemyan Dec 29 '13 at 16:18
  • 1
    XDocument doc = XDocument.Load(fileName); foreach (XElement el in doc.Root.Elements("Request")) { foreach (XElement field in el.Elements("Fields")) { foreach (XElement group in field.Elements("Group")){ output = group.Attribute("name").Value;}}} – Mohamed Salemyan Dec 29 '13 at 16:23
  • Thanks, I think now I got it, but my var output is still empty. – cherrycoding Dec 29 '13 at 17:17