【问题标题】:Why is org.w3c.dom parsing my xml wrong?为什么 org.w3c.dom 解析我的 xml 错误?
【发布时间】:2015-10-23 16:09:36
【问题描述】:

解析如下xml后,

<html>
    <body>
        <a>
            <div>
                <span>foo</span>
            </div>
        </a>
    </body>
</html>

用 javax.xml.xpath 解析的 org.w3c.dom 文档指示如下:

  • diva 的父节点
  • aspan 的父节点

这是为什么,我该如何正确解析这个 xml?

这是我正在使用的代码,后面是用于创建 Document 对象的方法,然后是代码的输出。

String myxml = ""
    + "<html>"
    + "<body>"
    + "<a>"
    + "<div>"
    + "<span>foo</span>"
    + "</div>"
    + "</a>"
    + "</body>"
    + "</html>";

Document doc = HttpDownloadUtilities.getWebpageDocument_fromSource(myxml);

XPath xPath = XPathFactory.newInstance().newXPath();

Node node = ((Node)xPath.compile("//*[text() = 'foo']").evaluate(doc, XPathConstants.NODE));

System.out.println("       node tag: " + node.getNodeName());
System.out.println("     parent tag: " + node.getParentNode().getNodeName());
System.out.println("grandparent tag: " + node.getParentNode().getParentNode().getNodeName());

Set<Node> nodes = H.getSet((NodeList)xPath.compile("//*").evaluate(doc, XPathConstants.NODESET));

for (Node n : nodes) {
    System.out.println();
    try {
        System.out.println("node: " + n.getNodeName());
    } catch (Exception e) {
    }
    try {
        System.out.println("child: " + n.getChildNodes().item(0).getNodeName());
    } catch (Exception e) {
    }
}

这里是用于创建 Document 对象的方法:

public static Document getWebpageDocument_fromSource(String source) throws InterruptedException, IOException {
    try {
        HtmlCleaner cleaner = new HtmlCleaner();
        CleanerProperties props = cleaner.getProperties();
        props.setAllowHtmlInsideAttributes(true);
        props.setAllowMultiWordAttributes(true);
        props.setRecognizeUnicodeChars(true);
        props.setOmitComments(true);

        DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance();
        DocumentBuilder builder = null;
        try {
            builder = builderFactory.newDocumentBuilder();
        } catch (ParserConfigurationException e) {
            e.printStackTrace();
        }

        TagNode tagNode = new HtmlCleaner().clean(source);

        Document doc = new DomSerializer(new CleanerProperties()).createDOM(tagNode);

        return doc;
    } catch (ParserConfigurationException ex) {
        ex.printStackTrace();
        return null;
    }
}

输出:

       node tag: span
     parent tag: a
grandparent tag: div

node: html
child: head

node: head

node: body
child: html

node: html
child: body

node: body
child: a

node: a

node: div
child: a

node: a
child: span

node: span
child: #text

【问题讨论】:

    标签: java xml xpath xml-parsing html-parsing


    【解决方案1】:

    html 解析器很可能修复了无效的 html。不允许在 a-tags 内使用 div-tags。一旦你有了 Document-object,html 就已经被解析并修复了。

    【讨论】:

    • 你知道有什么好的 xml 清理器不会重新排列我的节点吗?默认解析器在 a-tags 中使用 div 可以正常工作: Document doc = builder.parse(new ByteArrayInputStream(myxml.getBytes()));
    • 一个好的 html 解析器/清理器是 JSoup。但据我所知,如果结构无效,它也会重新排列结构。如果你不想改变结构,你应该使用纯 xml 解析。
    • 如果您希望在不重新排列的情况下对其进行解析,请使用 XML 解析器而不是 HTML 解析器。
    • @MichaelKay & johannesv 是否有任何 html 清理器可以配置为重新排列结构?或者,是否有任何纯 xml 清洁器?我的搜索结果为空
    • 您为什么需要清洁工?您显示的数据是格式良好的 XML,不需要清理。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-06-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-06-11
    • 2011-02-15
    • 2023-04-04
    相关资源
    最近更新 更多