1

Updated: I can only step down to the first value node in my XML. The code below gets to the first value node and shows data, but how would I select another node? I only need 3 values at the moment from each item node.The Tax Year, Bill number, and appl_amt, along with the image path are the only values I am working on retrieving. The Xml added is only a portion. The section added repeats several times until the BatchCompiler/Batch/transactions/transaction tags close the groupings.

   <?xml version="1.0"?>
 <BatchCompiler>
<batch>
   <batchid>95531</batchid>
   <transactions>
        <transaction>
            <items>
              <item>
                <values>
                  <value>
                     <name>doc_type</name>
                     <data>1</data> 
                  </value>
                  <value>
                    <name>doc_id</name>
                    <data>10</data>
                 </value>
                   <value>
                    <name>Bill Base Number</name>
                    <data>0007956700</data>
                 </value>
                 <value>
                    <name>Tax Year</name>
                    <data>2015</data>
                </value>
                 <value>
                    <name>Year For</name>
                    <data>2015</data> 
               </value>
                <value>
                   <name>Listing Type</name>
                   <data>0000</data>
              </value>
               <value>
                  <name>Postmark Date</name>
                   <data>08212015</data>
             </value>
            <value>
                   <name>appl_amt</name>
                   <data>18.12</data>
            </value>
            <value>
                    <name>tran_num</name>
                    <data>1</data>
           </value>
           <value>
                   <name>tran_seq</name>
                   <data>1</data>
           </value>
          </values>
          <image>..\images\95531_1_S_1.tif</image>
     </item>

 namespace GETZIP2
 {
 class Program
 {
    static void Main(string[] args)
    {
        XmlDocument doc = new XmlDocument();
        doc.Load("\\example\\index.xml);  
        MessageBox.Show(doc.SelectSingleNode("BatchCompiler/batch/transactions/transaction/items/item/values/value").InnerText);

    }

    }

 }

2 Answers2

1

LINQ to XML is a much better API than the old XmlDocument DOM, and LINQ to XML's query methods a lot nicer than messing around with XPath.

Something like this would probably work, though it would help if you showed some XML and were a little more specific about which values you actually want.

var doc = XDocument.Load(@"\example\index.xml");

foreach (var value in doc.Descendants("value"))
{
    var name = (string)value.Element("name");
    var data = (string)value.Element("data");

    // do something with these
}

If you wanted to query for a specific key/value pair, you could do something like:

var taxYear = doc.Descendants("value")
    .Where(e => (string)e.Element("name") == "Tax Year")
    .Select(e => (string)e.Element("data")
    .Single();

You might even consider creating a dictionary of all key/value pairs:

var keyValues = doc.Descendants("value")
    .ToDictionary(e => (string)e.Element("name"), e => (string)e.Element("data"));

var taxYear = keyValues["TaxYear"];
var billNumber = keyValues["Bill Base Number"];
Charles Mager
  • 25,735
  • 2
  • 35
  • 45
  • Thanks, i have added XML and info about the values I am working on – drummerORcoder Sep 09 '15 at 14:30
  • @drummerORcoder I've updated to include some more specifics following the addition of your XML. – Charles Mager Sep 09 '15 at 15:20
  • When I attempt to use the dictionary method, I receive a 'System.ArgumentException' : An item with the same key has already been added. – drummerORcoder Sep 16 '15 at 16:47
  • I can't seem to get around the fact that all the values are in identically named elements("name"/"data") – drummerORcoder Sep 16 '15 at 16:48
  • @drummerORcoder that's not likely to be the issue as the code would work with the (partial) XML you posted. I would guess your XML has multiple `item` elements and each contain `value` elements with the same `name`. Perhaps you could iterate each `item` using `doc.Descendants("item")` and then create a dictionary from each of these. – Charles Mager Sep 16 '15 at 17:48
-1

Besides Linq to XML, you can also use XmlReader class. It offers functions like ReadToNextSibling which help you move through siblings.

Other functions such as ReadToDescendant and MoveToNextAttribute might come in handy.

XmlReader reader = XmlReader.Create(@"\example\index.xml");

// Move to the desired element.
reader.MoveToContent();
reader.ReadToDescendant("value");
Hamed
  • 1,175
  • 3
  • 20
  • 46
  • Some XML elements are not content node. This function continue reading elements until it reaches a content node, then it will return that node as `XmlNodeType` object. [More info](https://msdn.microsoft.com/en-us/library/system.xml.xmlreader.movetocontent(v=vs.110).aspx) – Hamed Sep 16 '15 at 16:01