从 JSoup 选择器中过滤掉格式化标签

Filtering out formatting tags from JSoup selectors

JSoup 这里。我有以下 HTML 我正在尝试解析:

<html><head>
<title>My Soup Materials</title>
<!--mstheme--><link rel="stylesheet" type="text/css" href="../../_themes/ice/ice1011.css"><meta name="Microsoft Theme" content="ice 1011, default">
</head>
<body><center><table width="92%"><tbody>
<tr>
<td><h2>My Soup Materials</h2>

<table width="100%%" cellspacing="0" cellpadding="0">

<tbody>
<tr>
<td align="left"><b>Origin:</b> Belgium</td>
<td align="left"><b>Count:</b> 2 foos</td>
</tr>

<tr>
<td align="left"><b>Supplier:</b> </td>
<td align="left"><b>Must Burninate:</b> Yes</td>
</tr>

<tr>
<td align="left"><b>Type:</b> Fizzbuzz</td>
<td align="left"><b>Add Afterwards:</b> No</td>
</tr>

</tbody>
</table>
<br>
<b><u>Notes</b></u><br>Drink more ovaltine</td>
</tr>

</tbody>
</table>
</center></body>
</html>

不幸的是,它实际上有点格式错误(缺少一些结束标签,<b><u> 上的开始和结束标签不正常,等等)但我希望 JSoup 可以处理这个问题。我无法控制 HTML.

我有以下 Java model/POJO:

@Data // lombok; adds ctors, getters, setters, etc.
public class Material {
  private String name;
  private String origin;
  private String count;
  private String supplier;
  private Boolean burninate;
  private String type;
  private Boolean addAfterwards;
}

我正在尝试让 JSoup 解析此 HTML 并从该解析中提供一个 Material 实例。

要抓取里面的数据 <table> 我已经很接近了:

Material material = new Material();

Elements rows = document.select("table").select("tr");
for (Element row : rows) {

    // row 1: origin & count
    Elements cols = row.select("td");
    for (Element col : cols) {
        material.setOrigin(???);
        material.setCount(???);
    }

}

所以我能够得到每个 <tr>,并且对于每个 <tr> 得到它的所有 <td> 列。但是我挂断的地方是:

<td align="left"><b>Origin:</b> Belgium</td>

因此第一个 <td>col.text() 将是 <b>Origin:</b> Belgium如何告诉 JSoup 我只想要“比利时”?

我认为您正在寻找 tdNode.ownText()。也有简单的 text(),但是 as the docs state 这结合了节点 及其所有子节点 的所有文本节点并将它们标准化。换句话说,tdNode.text() 给你字符串 "Origin: Belgium"tdNode.ownText() 只给你 "Belgium"tdNode.child(0).ownText() 只给你 "Origin:".

您也可以使用 wholeText(),它是非规范化的,但我认为您需要此处的规范化(主要涉及去除空格)。