Search code examples
c#xmlxpathnamespacesselectsinglenode

How to iterate through all element in XML in Select Nodes


I am really new at c#. I am creating a project where I need to extract data from a XML file. I can select one single node and loop through the innertext of that element. But I have several elemt in the XML file. I want to loop throght all the elemt at once in a column. How can I dow that. I am explaining in detail.

Here is my XML file.

    <?xml version="1.0" encoding="utf-8"?>
<tlp:WorkUnits xmlns:tlp="http://www.timelog.com/XML/Schema/tlp/v4_4"
               xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
               xsi:schemaLocation="http://www.timelog.com/XML/Schema/tlp/v4_4 http://www.timelog.com/api/xsd/WorkUnitsRaw.xsd">
  <tlp:WorkUnit ID="130">
    <tlp:EmployeeID>3</tlp:EmployeeID>
    <tlp:AllocationID>114</tlp:AllocationID>
    <tlp:TaskID>239</tlp:TaskID>
    <tlp:ProjectID>26</tlp:ProjectID>
    <tlp:ProjectName>LIK Template</tlp:ProjectName>
    <tlp:CustomerId>343</tlp:CustomerId>
    <tlp:CustomerName>Lekt Corp Inc.</tlp:CustomerName>
    <tlp:IsBillable>1</tlp:IsBillable>
    <tlp:ApprovedStatus>0</tlp:ApprovedStatus>
    <tlp:LastModifiedBy>AL</tlp:LastModifiedBy>
  </tlp:WorkUnit>
  <tlp:WorkUnit ID="131">
    <tlp:EmployeeID>3</tlp:EmployeeID>
    <tlp:AllocationID>114</tlp:AllocationID>
    <tlp:TaskID>239</tlp:TaskID>
    <tlp:ProjectID>26</tlp:ProjectID>
    <tlp:ProjectName>LIK Template</tlp:ProjectName>
    <tlp:CustomerId>343</tlp:CustomerId>
    <tlp:CustomerName>Lekt Corp Inc.</tlp:CustomerName>
    <tlp:IsBillable>1</tlp:IsBillable>
    <tlp:ApprovedStatus>0</tlp:ApprovedStatus>
    <tlp:LastModifiedBy>AL</tlp:LastModifiedBy>
  </tlp:WorkUnit>

And here is my ConsumeReportingApi Class where I want to iterate throug the values.

    public class ConsumeReportingApi
    {
        private static readonly ILog Logger = LogManager.GetLogger(typeof (ConsumeReportingApi));

        public static void Consume()
        {
            if (ServiceHandler.Instance.TryAuthenticate())
            {
                if (Logger.IsInfoEnabled)
                {
                    Logger.Info("Successfully authenticated on reporting API");
                }

               var customersRaw = ServiceHandler.Instance.Client.GetWorkUnitsRaw(ServiceHandler.Instance.SiteCode,
                    ServiceHandler.Instance.ApiId,
                    ServiceHandler.Instance.ApiPassword,
                    WorkUnit.All,
                    Employee.All,
                    Allocation.All,
                    Task.All,
                    Project.All,
                    Department.All,
                    DateTime.Now.AddDays(-5).ToString(),
                    DateTime.Now.ToString()
                 );

                if (customersRaw.OwnerDocument != null)
                {
                    var namespaceManager = new XmlNamespaceManager(customersRaw.OwnerDocument.NameTable);
                    namespaceManager.AddNamespace("tlp", "http://www.timelog.com/XML/Schema/tlp/v4_4");

                    var customers = customersRaw.SelectNodes("tlp:WorkUnit", namespaceManager);
                    if (customers != null)
                    {
                        foreach (XmlNode customer in customers)
                        {
                             var taskId = customer.SelectSingleNode("tlp:TaskId", namespaceManager);
                          if (taskId != null)
                          {
                              if (Logger.IsDebugEnabled)
                              {
                                  Logger.Debug("Task ID "+taskId.InnerText);
                              }
                          }
                          var department = customer.SelectSingleNode("tlp:ProjectName", namespaceManager);
                          if (department != null)
                          {
                              if (Logger.IsDebugEnabled)
                              {
                                  Logger.Debug("Department ID: "+department.InnerText);
                              }
                          }
        }
    }
}

At this moment I set is tlp:TaskID inside customersRaw.SelectNodes method. But I want to get all other element os xml there and want to print those values. But I am not sure how to do this.

My Main Program class is

public class Program
{
    private static readonly ILog Logger = LogManager.GetLogger(typeof(Program));
    private static readonly DirectoryInfo AppPath = new FileInfo(Assembly.GetExecutingAssembly().Location).Directory;

    public static void Main(string[] args)
    {
   ....

        try
        {
            if (Logger.IsInfoEnabled)
            {
                Logger.Info("Running application");
            }

            // Run example classes
            ConsumeReportingApi.Consume();

        }
        catch (Exception ex)
        {
            ...
        }

        if (Logger.IsInfoEnabled)
        {
            Logger.Info("---");
            Logger.Info("Application loop ended. Click to exit");
        }

        // Wait for the user to end the application.
        Console.ReadKey();
    }
}

}


Solution

  • Try this if you want to log the inner text of all child nodes:

    var customers = customersRaw.SelectNodes("tlp:WorkUnit", namespaceManager);
    if (customers != null)
    {
        foreach (XmlNode customer in customers)
        {
            var childNodes = customer.SelectNodes("./*");
            if(childNodes != null)
            {
                foreach(XmlNode childNode in childNodes)
                {
                    if (Logger.IsDebugEnabled)
                    {
                        Logger.Debug(customerName.InnerText);
                    }
                }
            }
        }
    }
    

    If you want to get the inner text of a specific node that you know the name of, you could use SelectSingleNode:

    var childNode = customer.SelectSingleNode("./tlp:CustomerId", namespaceManager);
    if(childNode != null)
        Debug.WriteLine(childNode.InnerText);