Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/html/82.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java j组选择器:h2后的第二个div_Java_Html_Css Selectors_Jsoup - Fatal编程技术网

Java j组选择器:h2后的第二个div

Java j组选择器:h2后的第二个div,java,html,css-selectors,jsoup,Java,Html,Css Selectors,Jsoup,我有以下HTML: <html> <body> ... <h2> Blah Blah 1</h2> <p>blah blah</p> <div> <div> <table> <tbody> <tr><th>Col 1 Header</th><th>

我有以下HTML:

<html>
<body>

...

<h2> Blah Blah 1</h2>
<p>blah blah</p>
<div>
    <div>
        <table>
            <tbody>
                <tr><th>Col 1 Header</th><th>Col 2 Header</th></tr>
                <tr><td>Line 1.1 Value</td><td>Line 2.1 Header</td></tr>
                <tr><td>Line 2.1 Value</td><td>Line 2.2 Value</td></tr>
            </tbody>
        </table>
    </div>
</div>
<div>
    <div>
        <table>
            <tbody>
                <tr><th>Col 1 Header T2</th><th>Col 2 Header T2</th></tr>
                <tr><td>Line 1.1 Value T2</td><td>Line 2.1 Header T2</td></tr>
                <tr><td>Line 2.1 Value T2</td><td>Line 2.2 Value T2</td></tr>
                </tbody>
        </table>
    </div>
</div>

<h2> Blah Blah 2</h2>

<div>
    <div>
        <table>
            <tbody>
                <tr><th>XCol 1 Header</th><th>XCol 2 Header</th></tr>
                <tr><td>XLine 1.1 Value</td><td>XLine 2.1 Header</td></tr>
                <tr><td>XLine 2.1 Value</td><td>XLine 2.2 Value</td></tr>
            </tbody>
        </table>
    </div>
</div>
<p>blah blah</p>
<div>
    <div>
        <table>
            <tbody>
                <tr><th>XCol 1 Header T2</th><th>XCol 2 Header T2</th></tr>
                <tr><td>XLine 1.1 Value T2</td><td>XLine 2.1 Header T2</td></tr>
                <tr><td>XLine 2.1 Value T2</td><td>XLine 2.2 Value T2</td></tr>
                </tbody>
        </table>
    </div>
</div>

</body>
</html>
但要提取第二个,将“Blah 1”替换为“Blah 2”将不起作用,因为“p”标记位于其他位置,因此静态选择器将是:

h2:contains(Blah 2) + div + p +div
我需要的是一个单一的选择器公式,在这个公式中,无论p块在哪里,只要改变文本,它就会工作

我尝试了几种方法: 喜欢类型的选择器n也不起作用,因为我知道DIV的位置只对应于h2,它不是DIV的父亲,而是前面的兄弟姐妹


请帮忙

我有两个办法来实现这一点。
第一个是删除每个
,然后只需选择
“h2:contains(“+text+”)+div+div”
。请小心,只有当您确定您的
不包含任何
时才使用它。否则它将缺少一些内容

    public void execute1(String html) {
        Document doc = Jsoup.parse(html);
        // first approach: remove every <p> to simplify document
        Elements paragraphs = doc.select("p");
        for (Element paragraph : paragraphs) {
            paragraph.remove();
        }
        // then one selector will return what you want in both cases
        System.out.println(selectSecondDivAfterH2WithText(doc, "Blah 1"));
        System.out.println(selectSecondDivAfterH2WithText(doc, "Blah 2"));
    }

    private Element selectSecondDivAfterH2WithText(Document doc, String text) {
        return doc.select("h2:contains(" + text + ")+div+div").first();
    }

我还有第三个想法,使用类型为(2)的第n个div:h2:contains(“+text+”)。它对第一种情况有效,但对第二种情况无效,可能是因为div之间有一个

一个简单的方法是使用逗号(
)查询运算符,它在选择器之间执行OR。因此,您可以将
P
标记所在位置的两种变体组合起来

h2:contains(Blah 2) + div ~ div, h2:contains(Blah 2) ~ div + div

这里是操场上的一个例子。

为了澄清“包含给定文本”:您是否希望选择h2标记后面的第二个div,该标记本身包含“blah2”?如果是,p标签的功能是什么?使用支持xpath的库(如xsoup)将更容易做到这一点;这是一个选项吗?我需要迭代来提取H2后面的第二个DIV,该H2包含在每次迭代时更改的文本。你完全正确,杰克;Xpath很好,但不幸的是,我使用的是基于jsoup的工具:(嗨,Jonathan,我最后写了一些Java代码,因为我无法列举所有可能的情况,因为提供的代码仅用于testin,但我需要废弃的HTM页面比itHy Kristian复杂得多,我想避免使用Java,但最终没有编码就无法做到:)
    public void execute2(String html) {
        Document doc = Jsoup.parse(html);
        System.out.println(selectSecondDivAfterH2WithText2(doc, "Blah 1"));
        System.out.println(selectSecondDivAfterH2WithText2(doc, "Blah 2"));
    }

    private Element selectSecondDivAfterH2WithText2(Document doc, String text) {
        int counter = 2;
        // find h2 with given text
        Element h2 = doc.select("h2:contains(" + text + ")").first();
        // select every sibling after this h2 element
        Elements siblings = h2.nextElementSiblings();
        // loop over them
        for (Element sibling : siblings) {
            // skip everything that's not a div
            if (sibling.tagName().equals("div")) {
                // count how many divs left to skip
                counter--;
                if (counter == 0) {
                    // return when found nth div
                    return sibling;
                }
            }
        }
        return null;
    }
h2:contains(Blah 2) + div ~ div, h2:contains(Blah 2) ~ div + div