我正在研究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
任何帮助将不胜感激😊
您可以使用getFirstChild()
,getFirstChild()
和getNextSibling()
方法浏览DOM树来做到这一点:
getNextSibling()
该代码使用Java 11+ getParentNode()
方法缩进文本。对于Java的早期版本,请使用其他机制。
输出
getParentNode()
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="'
' || 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应用程序中调用。
下面的代码应根据您的要求进行: