Search code examples
c#xmllinq-to-xmlhtml-agility-packxmldocument

Looping the table in c# given all the values..?


I've table like this

<table>
  <tbody>
    <tr>
       <td>Header1</td>
       <td>Header2</td>
       <td>Header3</td>
       <td>Header4</td>
    </tr>
    <tr>
       <td>1</td>
       <td>2</td>
       <td>3</td>
       <td>4</td>
    </tr>
    <tr>
       <td>11</td>
       <td>22</td>
       <td>33</td>
       <td>44</td>
    </tr>

  </tbody>
</table>

My code is

var headersList = xmlDoc.XPathSelectElements("//table//tbody//tr").ToList();

But headerlist is giving all the td values :-(

Now I would like to know how can loop this table. My expected result as below:

First loop expected result

Header1 = 1,
Header2 = 2,
Header3 = 3,
Header4 = 4,

Second loop expected result:

Header1 = 11
Header2 = 22
Header3 = 33
Header4 = 44

Any help would be really appreciated


Solution

  • Since you have no way to distinguish between header and body (lack of thead, tbody) you will need to determine the number of elements programmatically.

    var data = @"<table>
      <tbody>
        <tr>
           <td>Header1</td>
           <td>Header2</td>
           <td>Header3</td>
           <td>Header4</td>
        </tr>
        <tr>
           <td>1</td>
           <td>2</td>
           <td>3</td>
           <td>4</td>
        </tr>
        <tr>
           <td>11</td>
           <td>22</td>
           <td>33</td>
           <td>44</td>
        </tr>
    
      </tbody>
    </table>";
    
    var xDoc = XDocument.Parse(data);
    var headerElements = xDoc.XPathSelectElements("//table//tbody//tr");
    int headerCount = headerElements.First().Descendants().Count();
    var nodes = headerElements.SelectMany(x => x.Descendants())
                              .Select(x => x.Value)
                              .ToList();
    var head = nodes.Take(headerCount).ToList();
    var body = nodes.Skip(headerCount).ToList();
    
    var pairs = new List<Tuple<string,string>>();
    
    for(var i = 0; i < body.Count; i += headerCount)
    {
        for(int j = 0; j < head.Count; j++)
        {
            pairs.Add(Tuple.Create(head[j], body[i+j]));
        }
    }
    
    foreach(var pair in pairs)
    {
        Console.WriteLine("{0} = {1}", pair.Item1, pair.Item2);
    }