JSoup从表td中提取文本,其中不包含任何html节点

时间:2016-01-20 09:34:16

标签: java jsoup

我有一个像这样的html字符串:

String html="<table><tbody>
<tr>
<td><p>ABC</p></td>
<td>DEF</td>
</tr>
<tr>
<td><p>GHI</p></td>
<td>MNO</td>
</tr>
</tbody>
</table>";

我只需要提取 td 标签内没有更多子元素的文本。我当前的代码都返回了text和html节点。

Elements elements = doc.select("tbody > tr");
for (Element e : elements) {
    System.out.println(e.select("td").html());
}

但我需要的是外线:

DEF
MNO

提前致谢。

3 个答案:

答案 0 :(得分:2)

我不清楚,如果您只想要每个td的文本,而不是td的孩子的端口,或者您想要进一步排除所有tds,有孩子。因此,您可能需要稍微调整我的解决方案。

String html="<table><tbody>"
        +"<tr>"
        +"<td><p>ABC</p></td>"
        +"<td>DEF</td>"
        +"<td>DEF2<p>ABC</p></td>"
        +"</tr>"
        +"<tr>"
        +"<td><p>GHI</p></td>"
        +"<td>MNO</td>"
        +"<td>MNO2<p>GHI2</p></td>"
        +"</tr>"
        +"</tbody>"
        +"</table>";

Document doc = Jsoup.parse(html);
Elements elements = doc.select("tbody > tr > td:matchesOwn(.+)");
for (Element e : elements) {
    System.out.println(e.text());
}

上述解决方案查找具有任何自己文本的td元素,即与正则表达式.+匹配的元素(至少一个字符)。

如果你想进一步淘汰含有孩子的tds,你可以这样做:

Document doc = Jsoup.parse(html);
Elements elements = doc.select("tbody > tr > td:matchesOwn(.+):not(:has(*))");
for (Element e : elements) {
    System.out.println(e.text());
}

这同时使用了:has()

中所解释的:not()和{{1}}伪选择器

答案 1 :(得分:2)

试试这个CSS选择器:

tbody > tr > td:not(:has(*))

样本

http://try.jsoup.org/~K4qiK0SxQDeuhE9FvvmUDa3vKKI

描述

tbody  /* Select any tbody */
> tr   /* Select any tr directly under it */
> td   /* Select any td directly under it ... */
:not(:has(*)) /* ... not having any element */

*运算符仅匹配元素。文本节点不是元素。它只是一种节点。

示例代码

Elements elements = doc.select("tbody > tr > td:not(:has(*))");
for (Element e : elements) {
    System.out.println(e.select("td").html());
}

输出

<td>DEF</td>
<td>MNO</td>

答案 2 :(得分:0)

使用index = 0尝试Element.child(int index)

Elements elements = doc.select("tbody > tr");
for (Element e : elements) {
    for (Element el : e.select("td")) {
        // el.child(0)
    }
}