0

I am reading XML file so that I can have all the necessary information to make a windows service.

The problem is that, I have to read all the task in XmlNodeList and then iterate to each Task element and read attribute.

My XML file look like this:

<Tasks>  
    <Task name="taskname1" type="tasktype1">   
        <Occurrence starttime="09:00" repeat="01:00" endtime="17:00" />       
        <FreeSpace disk=”C” />  
    </Task>
    <Task name="taskname2" type="tasktype2">   
        <Occurrence startime="11:00" repeat="00:05" endtime="13:00" />       
    </Task> 
</Tasks>

So what I want is that each task will be saved in a xmlNodeList and then for each task i have to read its child elements attribute and its values.

What I have achieved so far is that, I have been able to get the value of only first task which is free space on C.

My code is just reading first task.

        XmlNodeList xnList = xmlDoc.SelectNodes("/Tasks/Task");
        foreach (XmlNode task in xnList)
        {
            taskName = task.Attributes["name"].Value;//Name
            taskType = task.Attributes["type"].Value;//Type
            Console.WriteLine(taskName + " " + taskType);
        }
        XmlNodeList List = xmlDoc.SelectNodes("/Tasks/Task/Occurrence");
        foreach (XmlNode task1 in List)
        {
            taskStartTime = task1.Attributes["starttime"].Value;//starttime
            taskRepeat = task1.Attributes["repeat"].Value;//rpt
            taskEndTime = task1.Attributes["endtime"].Value;//endtime
            Console.WriteLine(taskStartTime + " " + taskRepeat + " " + taskEndTime);
        }
  • Apologies that this does not answer your question, but what you are doing would be immensely easier using Linq to Xml. Load your Xml into an XDocument and just use Linq to query it for the XElements you want. The attributes are then just a collection of XAttribute objects on the XElement. – Kevin Mar 08 '16 at 19:31
  • @Kevin I have to do it without using linq – Aniq Makhani Mar 08 '16 at 19:32
  • Have you tried putting a stop on the second line and debugging to see how many tasks you end up with in the list? – Kevin Mar 08 '16 at 19:33
  • My code is reading `taskName` and `taskType` of both task, and also `Occurrence` of task1. Then its giving me NullReferenceException. – Aniq Makhani Mar 08 '16 at 19:39
  • I understand what you code is attempting. Your for loops look fine, so I'm suspecting that you are, for some reason, only getting one XmlNode in xnList and I was asking you to use debug mode of your IDE to confirm or deny that assertion. – Kevin Mar 08 '16 at 19:47
  • @Kevin After Debugging, I looked at the XML file and I found the error, the `t` in `startime` was missing. – Aniq Makhani Mar 08 '16 at 19:59
  • Glad you were able to find the cause of the issue. – Kevin Mar 08 '16 at 20:00
  • @Kevin can you help me do this using only one foreach loop? I mean, can we read Task attribute and Occurrence attribute using only one foreach loop. – Aniq Makhani Mar 08 '16 at 20:01
  • You could, the only problem would be printing them out in the same order as you are now. – Kevin Mar 08 '16 at 20:18
  • I highly recommend you migrate to using XDocument and Linq. It's not only easier to read but faster to write (my opinion). – Erik Philips Mar 08 '16 at 20:38
  • See recursive method in following posting : http://stackoverflow.com/questions/28976601/recursion-parsing-xml-file-with-attributes-into-treeview-c-sharp – jdweng Mar 08 '16 at 22:19

1 Answers1

0

Something like this perhaps:

    XmlNodeList xnList = xmlDoc.SelectNodes("/Tasks/Task");
    foreach (XmlNode task in xnList)
    {
        taskName = task.Attributes["name"].Value;//Name
        taskType = task.Attributes["type"].Value;//Type
        if(task.HasChildNodes)
        {
            XmlNodeList child = task.ChildNodes();
            if(child != null)
            {
                taskStartTime = child[0].Attributes["starttime"].Value;//starttime
                taskRepeat = child[0].Attributes["repeat"].Value;//rpt
                taskEndTime = child[0].Attributes["endtime"].Value;//endtime
            }
        }
        // Do your output here where you have all the values for a task
        // Make sure you print before the next line, it will clear out the attribute values.
        taskStartTime = taskRepeat = taskEndTime = string.Empty;
    }
Kevin
  • 1,462
  • 9
  • 9
  • When I output the values, task1 values are fine, but the `starttime`, `repeat` and `endtime` of task2 is as same as taks1. – Aniq Makhani Mar 08 '16 at 20:46
  • Do you get the correct taskName and taskType for task 2? – Kevin Mar 08 '16 at 20:51
  • Yes, but attributes of occurrence are same as their previous task. – Aniq Makhani Mar 08 '16 at 21:02
  • I changed the line `XmlNodeList child = task.SelectNodes("/Occurrence");` to `XmlNodeList child = task.SelectNodes("/Tasks/Task/Occurrence");` then I was able to output the starttime etc of task1. – Aniq Makhani Mar 08 '16 at 21:06
  • Try the update above (changed task.SelectNodes to task.ChildNodes) – Kevin Mar 08 '16 at 21:12
  • I'm out of here in a few minutes. We are close, you'll have to experiment with what is needed to get the children of a particular node. This is why I switched to Linq to Xml and never looked back, it is so much easier to work with. – Kevin Mar 08 '16 at 21:16
  • Great, glad I could help – Kevin Mar 08 '16 at 21:23