Jsoup - 根据同一td中两个p标签的值选择一个表

时间:2016-09-23 00:53:16

标签: jsoup

我有一个有多个表的html。我想根据某些条件选择几张表。

我需要根据包含两个<p>标签的tr标签选择表格。 我想检查SAME tr标记下的<p>标记的值。

<table>
<tr>
<td>
<p>ABCD</p>
<p>HELLO</p>
</td>
</tr>
</table>

<table>
<tr>
<td>
<p>ABCD</p>
<p>BYE</p>
</td>
</tr>
</table>

<table>
<tr>
<td>
<p>ABCD</p>
<p>HELLO</p>
</td>
</tr>
</table>

我可以使用

轻松选择其中一项
 for (Element table : doc.select("table")) {
    for (Element row : table.select("tr")) {                        
        for (Element tds : table.select("td")) {
               tds.text().contains("ABCD");
               table.append(table.outerhtml);
         }
    }
 }

其中table是字符串构建器

1 个答案:

答案 0 :(得分:0)

使用element.html()(或element.outerHtml()),我们可以获取HTML代码的String表示形式。然后我们可以组合多个包含验证。

<强>代码

StringBuilder tableBuilder = new StringBuilder();

for (Element table : doc.select("table")) {
    String innerHtml = table.html();
    if(innerHtml.contains("ABCD") && innerHtml.contains("HELLO")) tableBuilder.append(table.outerHtml());
}

System.out.println(tableBuilder.toString());

如果真的很重要,那两个模式都在同一个tr标签内,我会引入一些标志来标记匹配,以避免使用正则表达式:

StringBuilder tableBuilder = new StringBuilder();

boolean firstPatternFlag = false;
boolean secondPatternFlag = false;

tableloop:
for (Element table : doc.select("table")) {
    for (Element trElement : table.select("tr")) {
        firstPatternFlag = false;
        secondPatternFlag = false;

        for (Element tdElement : trElement.select("td")) {
            if(tdElement.text().contains("ABCD")) firstPatternFlag=true;
            if(tdElement.text().contains("HELLO")) secondPatternFlag=true;
        }
        if(firstPatternFlag && secondPatternFlag){
            tableBuilder.append(table.outerHtml());
            continue tableloop;
        }
    }
}

更新1

评论中的规范:

  

我想唯一地检查第一个<p>标签是否包含ABCD和   第二个<p>标记包含HELLO

StringBuilder tableBuilder = new StringBuilder();

for (Element table : doc.select("table")) {
    Elements pElement = table.select("tr").first().select("p");
    if(pElement.size()>2 && pElement.get(0).text().contains("ABCD") && pElement.get(1).text().contains("HELLO")) tableBuilder.append(table.outerHtml());
}

更新2

只有第一行?

  

它不仅仅是第一个,而是全部。我有2个列表   多行。 Evert <tr>代码包含2个<td>代码,每个<td>代码都有一个代码   <p>标记。所以我需要在第一个<tr> <p>内检查<td>   第一个<p>内部包含ABCD,第二个<td>内部包含ABCD   第二个<p>包含HELLO。

我认为这意味着:......第二个<td>

中的第一个 <table> [<tr>...</tr>] <tr> <td> <p>ABCD</p> </td> <td> <p>HELLO</p> </td> </tr> [<tr>...</tr>] </table>

所以这会导致以下结构:

<td>

所以我们必须测试每个表中的每一行。如果至少存在两个<p>元素,我们会检查前两个td元素是否包含至少一个Document doc = Jsoup.parse(...); //source not specified in question StringBuilder tableBuilder = new StringBuilder(); for (Element table : doc.select("table")) { // check every table for (Element tr : table.select("tr")) { // check every row Elements tdElements = tr.select("td"); if (tdElements.size() < 2) { // row contains at least two <td> elements continue; } Elements firstTdPElements = tdElements.get(0).select("p"); Elements secondTdPElements = tdElements.get(1).select("p"); if (firstTdPElements.isEmpty() || secondTdPElements.isEmpty()) { // first and second <td> contain at least one <p> element continue; } // first p in first td contains "ABCD" // first p in second td contains "Hello" if (firstTdPElements.get(0).text().contains("ABCD") && secondTdPElements.get(0).text().contains("HELLO")) { tableBuilder.append(table.outerHtml()); } } } 标记,并比较文本节点。

<强>代码

$('.ui-dialog-titlebar-close').on('click', function(){
    console.log('inside close');
    $('.ui-dialog').dialog("close");
    });