【问题标题】:How to get only n-level elements with Jsoup?如何使用 Jsoup 仅获取 n 级元素?
【发布时间】:2018-04-18 20:07:28
【问题描述】:

我有一个包含多个层次的巨大目录:

我需要对其进行编辑并仅保留 Level1Level2 的元素并删除其他所有内容,如:

为此我使用 Jsoup:

File in = new File(INPUT_FILE_PATH);
Document origDoc = Jsoup.parse(in, null);
Elements toc = origDoc.getElementsByClass("toc");
Elements firstLevelChildElements = toc.select("ul");

然后我想分析元素,如果元素只有一个父元素 - 保留它,否则删除它。

但问题是firstLevelChildElements 选择了第一个ul 及其所有子代。当我尝试选择下一个子元素时也会发生同样的情况。我不能只拥有所有元素的列表(或树)。

示例 HTML 代码为:

<ul class="toc">
    <li>
        <a href="#toc_20">Level 1</a>
        <ul>
            <li>
                <a href="#toc_21">Level 2</a>
                <ul>
                    <li>
                        <a href="#toc_22">Level 3</a>
                    </li>
                </ul>
            </li>
            <li>
                <a href="#toc_28">Level 2</a>
            </li>
            <li>
                <a href="#toc_29">Level 2</a>
            </li>
        </ul>
    </li>
    <li>
        <a href="#toc_20">Level 1</a>
        <ul>
            <li>
                <a href="#toc_21">Level 2</a>
                <ul>
                    <li>
                        <a href="#toc_22">Level 3</a>
                    </li>
                </ul>
            </li>
        </ul>
    </li>
</ul>

This answer 很好,但不幸的是对我不起作用。

【问题讨论】:

  • 您的示例是输入。你能告诉我们你想从这个输入中产生什么输出吗?在我看来,级别 1 是两个列表项,级别 2 是四个列表项。您是否能够修改 HTML 以添加 &lt;li class="level2"&gt;?这将简化 Jsoup 选择器。
  • @ThisClark 谢谢你的评论,我更新了这个问题。问题是所有lis 和uls 都没有类。
  • 好的,我知道您期望的输出是修改后的 HTML,与您的第二个屏幕截图完全相同。对吗?
  • 我想这是我最后一个问题了——既然你是用Java写的,最后你想得到什么数据类型?您想要 HTML 的 String、修改后的 HTML 的 Jsoup Document 还是 Elements 的集合?
  • @ThisClark 这是正确的,我希望修改后的 HTML,如第二张图片所示。我想获得 HTML 的String,因为我还想用新的目录替换目录。

标签: java html jsoup


【解决方案1】:

使用 Jsoup,您可以操作 dom。选择所有不需要的元素并清空它们的 html。您可以使用 css 选择器来执行此操作:

    Document doc = Jsoup.parse(html);
    for (Element e : doc.select("ul > li > ul > li > ul")) {
        e.html("");
    }

或更一般地选择具有 toc 类的 ul 元素的所有四阶子元素:

    Document doc = Jsoup.parse(html);
    for (Element e : doc.select("ul.toc > * > * > * > * > *")) {
        e.html("");
    }

然后从修改后的文档中选择需要的元素。

更多关于 CSS 选择器的信息:

https://www.w3schools.com/cssref/css_selectors.asp

https://jsoup.org/cookbook/extracting-data/selector-syntax

【讨论】:

  • 感谢您的回复,但通过这种方法,我得到的只是空字符串 &lt;li&gt;&lt;/li&gt;&lt;li&gt;&lt;/li&gt;&lt;ul&gt;&lt;/ul&gt;&lt;li&gt;&lt;/li&gt;
  • 我已经在您提供的示例 html 上对此进行了测试。如果您的实际 html 不同,则需要调整代码。
  • 我使用相同的 HTML sn-p,我将 System.out.println(e); 放在循环中,并且只得到了那个空标签。
  • 循环后添加 System.out.println(doc)
  • 在循环中,您可以制作 3 级或更多空的标签。在循环之后你有没有这个标签的 html,即只有第 1 级和第 2 级
猜你喜欢
  • 2018-08-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-01-27
  • 2016-10-06
  • 2023-03-24
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多