如何递归解析 HTML 元素

How to parse HTML elements recursively

提问人:Sai 提问时间:10/7/2022 更新时间:10/7/2022 访问量:183

问:

我有下面的HTML,需要递归解析。为此,我正在使用 Jericho html 解析器库。但是无法实现递归。感谢指点!

[HTML全

<div wicket:id="Container1">
        <div wicket:id="Panel1"></div>
        <form wicket:id="sampleForm" action="">
            <div id="InterstitialPanel" class="usaa-interstitial s1"></div>
            <div wicket:id="DisclosureSection">
                <div class="sample class">
                    <ul>
                        <li>Item 1</li>
                        <li>Item 2</li>
                        <li>Item 3</li>
                        <li>Item 4</li>
                    </ul>
                </div>
            </div>
        </form> 
    </div>

    <div wicket:id="Container2">
        <h2>This is container 2</h2>
    </div>

预期 O/p

在这里,我从原始 html 中获取一个值并从中创建一个新标签。如果它是标准的 HTML 标记(没有 wicket 属性),请保持原样。wicket:id

<Container1> 
<Panel1></Panel1>
<Form id="sampleForm">
    <InterstitialPanel></InterstitialPanel>
    <DisclosureSection>
        <div class="sample class">
                    <ul>
                        <li>Item 1</li>
                        <li>Item 2</li>
                        <li>Item 3</li>
                        <li>Item 4</li>
                    </ul>
        </div>
    </DisclosureSection>
</Form>
这是容器 2

Java 代码

public static void main(String args[]){
 Main m = new Main();
 File file = new File("C:\\USAAPoC\\ClientSamplePage.html");
 Source doc = new Source(file);
 Element element = doc.getElementByTag("body");
 m.processBody(element, new ReactPageContext());
}

private StringBuilder processBody(Element element, ReactPageContext reactPageContext) {
        StringBuilder sb = new StringBuilder();
        if (!element.getChildElements().isEmpty()) {
            element.getChildElements().stream().forEach(child -> sb.append(processTag(child, reactPageContext)));
        } else {
            sb.append("<Container>\n");
        }

        return sb;
    }
    
    
private StringBuilder processTag(Element element, ReactPageContext reactPageContext) {
        StringBuilder sb = new StringBuilder();

        element.getAllElements().stream().forEach(child -> {
                if (child.getName().equals("div") && child.getAttributes().get("wicket:id") != null) {
                    sb.append("<Container>");
                } else if (child.getName().equals("form")) {
                        
                        sb.append("<Form>"
                        List<Element> allChildFormElements = outputDocument.getSegment().getAllElements();
                        allChildFormElements.stream().forEach(childFormElement -> {
                            if (childFormElement.getName().equals("div")
                                    && childFormElement.getAttributes().get("wicket:id") != null) {
                                    sb.append("<Container>");
                            } else {
                                //logic
                            }
                        });
                }
        });

        return sb;
    }```
Java 递归 HTML 解析

评论


答:

0赞 queeg 10/7/2022 #1

您的 processTag 方法似乎关心创建开始标记 (),但从不添加结束标记 ()。最重要的是,您将 dom 树序列化为 String,如果操作不当,会添加很多古怪之处。<Container></Container>

总而言之,最好使用 XSLT 替换标记,然后使用 Java 的内置序列化程序来获取 XML 文档。这在使用 Java 的 XSLT 处理中得到了本质的体现?