0

I have this xml, and I am lost reading it, please can anyone help?

<?xml version = "1.0" encoding = "utf-8"?>
<root>
    <batch> 
    <field   level = "batch" name = "VoucherNumber" value = "00018"/>
    <field   level = "batch" name = "FinancialYear" value = "1996"/>
    <field   level = "batch" name = "CountNumber" value = "00018"/>
    <field   level = "batch" name = "CountDate" value = "1416-08-16"/>
    <field   level = "batch" name = "Total" value = "214000.0"/>
    <field   level = "batch" name = "CuttOf" value = "0.0"/>
    <field   level = "batch" name = "Net" value = "214000.0"/>
    <field   level = "batch" name = "Comment" value = "1"/>
    <field   level = "batch" name = "DailyNumber" value = "00018"/>
    <field   level = "batch" name = "DailyDate" value = "1416-09-01"/>
    <field   level = "batch" name = "Year" value = "1416"/>
    <field   level = "batch" name = "Section" value = "1"/>
    </batch> 
</root>

I am trying to extract all the names and values and return them, my code as follow:

private string ReadXML(string filename)
{
string str = "";
XmlDocument doc = new XmlDocument();
doc.Load(filename);
XmlNodeList nodelist = doc.SelectNodes("/root/batch");
foreach (XmlNode node in nodelist)
{
str += node["name"].InnerText + node["value"].InnerText;
}
return str;
}
Filburt
  • 17,626
  • 12
  • 64
  • 115
Abd H.
  • 3
  • 2
  • possible duplicate of [Read XML Attribute using XmlDocument](http://stackoverflow.com/questions/933687/read-xml-attribute-using-xmldocument) – MethodMan Aug 20 '15 at 15:17

5 Answers5

0

"name" and "value" are attributes of the xml node. To access them:

node.Attributes["name"].Value;
node.Attributes["value"].Value;

so, this line should look something like:

str += node.Attributes["name"].Value + node.Attributes["value"].Value;
devlin carnate
  • 8,309
  • 7
  • 48
  • 82
  • thanks. that works. I only had to do a little change up to include the field node in XmlNodeList nodelist = doc.SelectNodes("/root/batch/field") – Abd H. Aug 21 '15 at 05:06
0

I find LinqToXml easier to use

var dict = XDocument.Load(filename)
           .Descendants("field")
           .ToDictionary(f => f.Attribute("name").Value, f => f.Attribute("value").Value);


foreach(var kv in dict)
{
    Console.WriteLine(kv.Key + " " + kv.Value);
}
Eser
  • 12,346
  • 1
  • 22
  • 32
  • that is great. I want to use your code, but can I know first if it the execution is faster than my piece of code? as I need to run it on millions of documents. – Abd H. Aug 21 '15 at 05:11
0

You need to change your selected nodes to look for the field node. You will also need to access the attributes of the nodes in your foreach loop, which will look something like this:

XmlNodeList nodelist = doc.SelectNodes("/root/batch/field");
foreach (XmlNode node in nodelist)
{
    str += node.Attributes["name"].InnerText + node.Attributes["value"].InnerText;
}

You can also change the .InnerText to .Value, but both are working for me.

Matt
  • 1,230
  • 16
  • 19
0

XDocument also can be used instead of XMLDocument:

private string ReadXML(string filename)
{
    string str = "";
    XDocument doc = XDocument.Load(filename);
    IEnumerable<XElement> rows = doc.Root.Descendants("field");
    foreach (XElement node in rows)
    {
       str += node.Attribute("name").Value + node.Attribute("value").Value;
    }
    return str;
}

You can try it here: https://dotnetfiddle.net/CaQ6T2

currarpickt
  • 2,290
  • 4
  • 24
  • 39
0

I would go with LinqToXml and do this:

private string ReadXML(string filename)
{
    return String.Join("",
        from d in XDocument.Load(filename).Descendants("field")
        let name = d.Attribute("name").Value
        let value = d.Attribute("value").Value
        from x in new [] { name, value }
        select x);
}
Enigmativity
  • 113,464
  • 11
  • 89
  • 172