我想得到一个位于元素后面的表格:
<body>
<h3>test</h3>
<table>
<tr><td>abc</td></tr>
</table>
<h3>test2</h3>
<table>
<tr><td>def</td></tr>
</table>
[...]
</body>
所以我只想在h3元素“test”之后获取表格(或者表格的内容,但我知道如何做这种事情)。 表“test”并不总是第一个,也可能在秒表之后的某个地方。
[编辑]
你知道为什么这段代码:
var doc = new HtmlAgilityPack.HtmlDocument();
doc.LoadHtml(html); //your test html
var s = doc.DocumentNode.Descendants("table").Where(_ => _.PreviousSibling.PreviousSibling.Name.Equals("h3") && _.PreviousSibling.PreviousSibling.InnerText.Equals("test"));
foreach (var st in s)
{
Debug.WriteLine(st.InnerHtml);
}
如果我在“/ h3”和“table”之后删除了返回,不起作用?
看起来像这样:
string html = @"<body><h3>test</h3><table><tr><td>abc</td></tr></table><h3>test2</h3><table><tr><td>def</td></tr></table></body>"
而不是上面的html代码,但结果是null ...
答案 0 :(得分:0)
这听起来像XPath:
var doc = new HtmlAgilityPack.HtmlDocument();
doc.LoadHtml(html); //your test html
var table = doc.DocumentNode.SelectSingleNode("//h3[text()='test']/following::table");
return table.InnerHtml; //returns: "\r\n <tr><td>abc</td></tr>\r\n "
XPath来自:XPath - Select first element after some other element
编辑2: 您的问题是不一定涉及文本元素。因此,你可以通过检查来解决这个问题:
var table3 = doc.DocumentNode.Descendants().FirstOrDefault(x =>
{
if (x.NodeType == HtmlAgilityPack.HtmlNodeType.Element)
{
if (x.PreviousSibling?.NodeType == HtmlAgilityPack.HtmlNodeType.Text)
{
return x.PreviousSibling.PreviousSibling?.Name == "h3" && x.PreviousSibling.PreviousSibling?.InnerText == "test";
} else
{
return x.PreviousSibling?.Name == "h3" && x.PreviousSibling?.InnerText == "test";
}
}
return false;
});
答案 1 :(得分:0)
你可以尝试这样的事情。我发现Linq更方便。这只是一个想法,你可以进一步扩展它或只是在这里发布你的问题,我们可以解决:)。 抱歉,我没有IDE。
var doc = new HtmlAgilityPack.HtmlDocument();
doc.LoadHtml(html); //your test html
doc.DocumentNode.Descendants("table").Where(_ => _.PreviousSibling.PreviousSibling.Name.Equals("h3"));
顺便说一句,我们需要两次调用previousSibling的原因是每个节点之间总有1个#text元素。