获取元素后面的 table

Get the table right behind an element

我想获取位于元素后面的 table:

<body>
    <h3>test</h3>
    <table>
        <tr><td>abc</td></tr>
    </table>

    <h3>test2</h3>
    <table>
        <tr><td>def</td></tr>
    </table>
    [...]
</body>

所以我只想获取 h3 元素 "test" 之后的 table (或 table 的内容,但我知道如何做这类事情)。 table "test" 并不总是第一个,也可能在 table.

秒之后的某个地方

[编辑]

你知道为什么这个代码:

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" 之后的 return,

不起作用?

看起来像这样:

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 代码,但结果为空...

这听起来像是 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;
            });

你可以尝试这样的事情。我发现 Linq 更方便。这只是一个想法,您可以进一步扩展它,或者 post 您的问题在这里,我们可以解决 :)。 抱歉,我没有带 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 元素。