如何使用DOM解析Java中的内联/混合内容xml元素

问题描述 投票:0回答:3

我正在研究xml解析,并从各种资源中学到了一些东西。我是Java领域的初学者,但我仍然想尽一切办法。

目前,我一直试图解析如下所示的内容:

<poem>
    <line>Hey diddle, diddle 
        <i>the cat</i> and the fiddle.
    </line>
</poem>

这不是实际的xml,但是实际的xml看起来并不差很多,所以我发布了它(我想是相同的主意)

我正在尝试获取类似这样的输出:

Element : line
    text : Hey diddle, diddle
    element: i
        text: the cat
    text: and the fiddle.
------------------------ 
OR
------------------------ 

line:   Hey diddle, diddle
    i: the cat
    and the fiddle

此刻我的代码如下:

public class parsingWithDOM {

    public static void main(String[] args) {
        File xml = new File("/Users.../xmlTest.xml");
        DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
        try {
            DocumentBuilder db = dbf.newDocumentBuilder();
            Document doc = db.parse(xml);

            NodeList nList = doc.getElementsByTagName("line");
            Node l = nList.item(0);
            if (l.getNodeType() == Node.ELEMENT_NODE) {
                Element line = (Element) l;
                System.out.println(line.getTagName()  + ": " + line.getTextContent());
                NodeList lineList = line.getChildNodes();
                for (int i = 0; i < lineList.getLength(); i++) {
                    Node node = lineList.item(i);
                    if (node.getNodeType() == Node.ELEMENT_NODE) {
                        Element lineElement = (Element) node;
                        System.out.println(lineElement.getTagName() + ": " + lineElement.getTextContent());
                    }
                }
            }

        } catch (IOException | ParserConfigurationException | DOMException | SAXException e) {
            System.out.println(e.getMessage());
        }

    }
}

无论如何,我得到的输出是这个(不是我想要的东西)

line: Hey diddle, diddle the cat and the fiddle.

i: the cat

任何帮助将不胜感激😊

java xml parsing dom
3个回答
0
投票

您可以使用getFirstChild()getFirstChild()getNextSibling()方法浏览DOM树来做到这一点:

getNextSibling()

该代码使用Java 11+ getParentNode()方法缩进文本。对于Java的早期版本,请使用其他机制。

输出

getParentNode()

0
投票

XSLT中的许多任务比Java / DOM中的任务简单得多,这是其中之一。这是使用XSLT 3.0的解决方案。

int level = 0;
Node node = doc.getDocumentElement();
while (node != null) {
    // Process node
    if (node.getNodeType() == Node.ELEMENT_NODE) {
        System.out.println("  ".repeat(level) + "Element: \"" + node.getNodeName() + "\"");
    } else if (node.getNodeType() == Node.TEXT_NODE || node.getNodeType() == Node.CDATA_SECTION_NODE) {
        String text = node.getNodeValue()
                .replace("\r", "\\r")
                .replace("\n", "\\n")
                .replace("\t", "\\t");
        System.out.println("  ".repeat(level) + "Text: \"" + text + "\"");
    }

    // Advance to next node
    if (node.getFirstChild() != null) {
        node = node.getFirstChild();
        level++;
    } else {
        while (node.getNextSibling() == null && node.getParentNode() != null) {
            node = node.getParentNode();
            level--;
        }
        node = node.getNextSibling();
    }
}

输出为

repeat​(int count)

您可以在以下位置看到它的运行状态>>

repeat​(int count)

与您交谈:

  • [Element: "poem" Text: "\n " Element: "line" Text: "Hey diddle, diddle \n " Element: "i" Text: "the cat" Text: " and the fiddle.\n " Text: "\n" 说您要输出文本,而不是XML或HTML

  • [<?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:f="http://local/" exclude-result-prefixes="#all" expand-text="yes" version="3.0"> <xsl:output method="text" /> <xsl:strip-space elements="*"/> <xsl:template match="*"> <xsl:text>{f:indent(.)}ELEMENT {name()}</xsl:text> <xsl:apply-templates/> </xsl:template> <xsl:template match="text()"> <xsl:text>{f:indent(.)}{.}</xsl:text> </xsl:template> <xsl:function name="f:indent" as="xs:string"> <xsl:param name="node" as="node()"/> <xsl:sequence select="'&#xa;' || string-join((1 to count($node/ancestor::*))!'__')"/> </xsl:function> </xsl:stylesheet> 说忽略输入中仅包含空格的文本节点

  • 有两个ELEMENT poem __ELEMENT line ____text: Hey diddle, diddle ____ELEMENT i ______text: the cat ____text: and the fiddle. 规则,一个用于元素,一个用于文本节点

  • 两者都调用函数https://xsltfiddle.liberty-development.net/gWEaSuR/1,该函数根据树中节点的深度(通过计算祖先找到)生成缩进

  • 此样式表中的大部分工作都是正确设置输出格式(输入导航会自行处理)。我在输出中使用了下划线而不是空格,因此您可以看到输入的空白​​与样式表生成的空白之间的区别。

JDK具有内置的XSLT 1.0处理器,但是XSLT 3.0具有许多额外的功能,为此,您需要安装Saxon。这两个处理器都可以很容易地从Java应用程序中调用。


-1
投票

下面的代码应根据您的要求进行:

© www.soinside.com 2019 - 2024. All rights reserved.