Unable to get list from xml using xPathNavigator

431 views Asked by At
List<string> list = new List<string>();
foreach (XPathNavigator node in nav.Select("configuration/company/work/worktime"))
            {
                string day = getAttribute(node, "day");
                string time = getAttribute(node, "time");
                string worktype = ?? // how to get worktype attribute valuefrom parent node 
              list.Add(day,time,worktype); // add to list 
            }

 </configuration>
      <company>
        <work worktype="homeWork">
            <worktime day="30" time="10:28"></worktime>
            <worktime day="25" time="10:50"></worktime>
         </work>
        <work worktype="officeWork">
            <worktime day="12" time="09:28"></worktime>
            <worktime day="15" time="12:28"></worktime>
        </work>
      </company>
    </configuration>


need output as :
list[0] = homeWork,30,10:28
list[1] = homeWork,25,10:50
list[2] = officeWork,12,09:28
list[3] = officeWork,15,12:28

I am trying to get the list from XML but failed to get output like given above (using xpath navigator, how can I access parent node to get worktype attribute, and other remaining inner node attribute?

3

There are 3 answers

2
Charles Mager On BEST ANSWER

I'd suggest using LINQ to XML over XPath, but if you must use XPathNavigator then you need to iterate each work element followed by each of its worktime child elements. This way you can use the worktype from the parent context:

foreach (XPathNavigator work in nav.Select("configuration/company/work"))
{
    var workType = work.GetAttribute("worktype", string.Empty);

    foreach (XPathNavigator worktime in work.Select("worktime"))
    {
        var day = worktime.GetAttribute("day", string.Empty);
        var time = worktime.GetAttribute("time", string.Empty);

        list.Add($"{workType}, {day}, {time}");
    }
}

See this fiddle for a working demo.

1
Macros On

Use a nested loop. Initially retrieve the work nodes with configuration/company/work. Retrieve the worktype attribute and store in a variable. Then loop through the child worktype nodes and add a string to the list for each one

3
jdweng On

Use Net Library enhanced xml (linq xml)

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

namespace ConsoleApplication1
{
    class Program
    {
        const string FILENAME = @"c:\temp\test.xml";
        static void Main(string[] args)
        {
            XDocument doc = XDocument.Load(FILENAME);
            var results = doc.Descendants("work").Select(x => new {
                worktype = (string)x.Attribute("worktype"),
                worktime = x.Elements("worktime").Select(y => new {
                    day = (int)y.Attribute("day"),
                    time = (DateTime)y.Attribute("time")
                }).ToList()
            }).ToList();
        }
    }
}