C# 通过使用XPath将相邻的表行分组来选择表行

C# 通过使用XPath将相邻的表行分组来选择表行,c#,xpath,C#,Xpath,我不清楚如何在问题中正确表达我的问题,所以如果我不能正确表达我的问题,请原谅我。我有以下数据 <tr class="header">Random Value 1</tr> <tr class="item">1</tr> <tr class="item">2</tr> <tr class="item">3</tr> <tr class="header">Random Value 2</

我不清楚如何在问题中正确表达我的问题,所以如果我不能正确表达我的问题,请原谅我。我有以下数据

<tr class="header">Random Value 1</tr>
<tr class="item">1</tr>
<tr class="item">2</tr>
<tr class="item">3</tr>
<tr class="header">Random Value 2</tr>
<tr class="item">4</tr>
<tr class="item">5</tr>
<tr class="item">6</tr>
<tr class="header">Random Value 3</tr>
<tr class="item">7</tr>
<tr class="item">8</tr>
<tr class="item">9</tr>
现在我有了集合中的所有标题行。现在我循环遍历所有的头节点,并希望得到与相应头行相邻的表行

foreach (HtmlNode node in headerNodes)
{
     HtmlNodeCollection itemNodes = ???
}

我的问题是,我应该在这里写什么,以便对于文本为“Random Value 1”的标题行,我得到项目行1、2和3。类似地,对于带有文本“Random Value 2”的标题行,我会得到项目行4、5和6,依此类推。

我不太确定HtmlNodeCollection是什么,但如果使用普通XPath并执行SelectNodes(这将返回XmlNodeCollection),则会找到使用node.NextSibling查找的元素。 因此,您的循环看起来像:

   foreach (XmlNode node in headerNodes)
   {
        string entry = node.NextSibling.InnerXml;
   }

我已经找到了我的问题的解决方案,经过大量的搜索和玩不同的选择。诀窍是通过检查前面的标题行来选择类为“item”的行。因此,您可以在XPath表达式中看到,我选择了一个类为“item”的tr,并且我还检查了它前面的类为“header”的tr必须具有当前头HtmlNode的innerText值。这就成功了

foreach (HtmlNode header in headerNodes)
{
   string xPath = "following-sibling::tr[contains(@class, 'item') and preceding-sibling::tr[@class='header'][1]='{0}']";
   HtmlNodeCollection itemRows = header.SelectNodes(String.Format(xPath, header.InnerText));
}

抱歉,我忘记告诉您我正在使用HtmlAlityPack,HtmlNodeCollection用于获取节点。您的答案仅在获得下一个兄弟姐妹时有效。项目行可能更多或更少,我需要获取标题行之后的所有项目行。我已经找到了答案,并向其他人提到了它。对,您需要将当前节点存储在循环中的某个位置,如:
foreach (HtmlNode header in headerNodes)
{
   string xPath = "following-sibling::tr[contains(@class, 'item') and preceding-sibling::tr[@class='header'][1]='{0}']";
   HtmlNodeCollection itemRows = header.SelectNodes(String.Format(xPath, header.InnerText));
}