【问题标题】:Get child elements that directly descent from parent with Jsoup?使用 Jsoup 获取直接从父级下降的子元素?
【发布时间】:2016-07-15 11:30:26
【问题描述】:

我的 HTML 树中有类似下面的内容。我想通过迭代div来创建一个JSON,记住哪个data-view实际上是哪个父data-view的子级。最终结果类似于{"main":{"header":{"navbar":"some txt","static":"some text"},"slider":"some txt","footer":"some txt"}}

<div id="loader-div"></div>
<div class="main-container">
    <div data-view="main" data-class="main_class">
        <div class="details_container">
            <h1>Helo Text</h1>
            <div data-view="header" data-class="header_class">
                <h2>Hello Header</h2>
                <div data-view="navbar" data-class="navbar_class">
                    <h2>sdf</h2>
                    <span data-text="navbarDataId">some text</span>
                </div>
                <div class="brder_bttm clearfix">
                    <div data-view="static" data-class="static_class">
                        <span data-text="navbarDataId">some text</span>
                        <button data-event="show_all" class="btn btn-block btn-success">Show All</button>
                    </div>
                </div>
                <span>some text</span>
            </div>
            <div class="slider_container">
                <div data-view="slider" data-class="slider_class">
                    <span data-text="sliderDataId">some text</span>
                </div>
            </div>
            <div data-view="footer" data-class="footer_class">
                <span data-text="footerDataId">some text</span>
            </div>
        </div>
    </div>
</div>

我试过了

for (int z = 0; z < doc.getElementsByAttributeStarting("data-view").size(); z++ ){
   String dtview= doc.getElementsByAttributeStarting("data-view").get(z).attr("mt-class")
}

但这给了我所有子元素并且无法找到哪些子元素属于哪个父元素?如果可以通过其他一些库实现相同的功能,我很乐意打开它。 更新:更新了我的 html 以获取确切的场景。请注意,

  • 我必须关注并迭代数据视图节点,只记住哪个节点实际上是哪个父节点的子节点。
  • 数据文本节点总是包含在某个数据视图节点中。
  • 请注意它包含数据文本节点的数据视图节点模式。

【问题讨论】:

  • 在您更新的示例中,预期输出是否相同?
  • @DavidePastore 我也更新了预期的 json 输出。虽然几乎一样。
  • @DavidePastore 你找到出路了吗?
  • 还没有,我正在处理这个。
  • 好的..我也在做同样的事情..

标签: java html-parsing jsoup jsonpath


【解决方案1】:

是的,您可以使用 Jsoup 来完成。我创建了一个递归方法,该方法将被调用以从您的 HTML 动态生成 JSON。

package com.github.davidepastore.stackoverflow38395047;

import org.json.JSONObject;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;

/**
 * Stackoverflow 38395047 answer.
 *
 */
public class App {
    public static void main(String[] args) {
        String html = "<div data-view=\"main\">\r\n"
                + "    <div data-view=\"header\">\r\n"
                + "        <div data-view=\"navbar\">\r\n"
                + "            <span>some text</span>\r\n"
                + "        </div>\r\n" + "        <span>some text</span>\r\n"
                + "    </div>\r\n" + "    <div data-view=\"slider\">\r\n"
                + "        <span>some text</span>\r\n" + "    </div>\r\n"
                + "    <div data-view=\"footer\">\r\n"
                + "        <span>some text</span>\r\n" + "    </div>\r\n"
                + "</div>";
        JSONObject json = new JSONObject();

        Document document = Jsoup.parse(html);
        Element body = document.select("body").first();
        json = (JSONObject) generateJson(body);
        System.out.println(json.toString(2));
    }

    public static Object generateJson(Element element){
        JSONObject json = new JSONObject();
        Elements children = element.children();
        for (Element child : children) {
            if(child.tagName().equals("div")){
                String dataView = child.attr("data-view");
                json.put(dataView, generateJson(child));
            } else if(json.keySet().size() == 0){
                return child.text();
            }
        }
        return json;
    }
}

输出:

{"main": {
  "footer": "some text",
  "slider": "some text",
  "header": {"navbar": "some text"}
}}

Additional library for JSON

【讨论】:

  • Superb Mate。但我有容器 div(s) 也有一些不同的类 n 属性,它在那些场景中中断。
  • 嗨@PrototypeChain,请编辑您的原始问题,以便我看到您的不同场景。
  • 用 html 更新我的问题。看它的模式伙伴。 data-view 节点可以在任何地方,也可以包裹在一些包装器 div 周围。而且,数据文本节点只能包含在某些数据视图节点中。
猜你喜欢
  • 2013-01-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-09-04
  • 1970-01-01
相关资源
最近更新 更多