约定:本文实践的JDK版本在8以上
原生JDK读取XML内容
- Java8 API参考手册 Java 8 中文版 - 在线API中文手册
总体步骤
- 创建
DocumentBuilderFactory
并配置,这是一个工厂对象 - 创建
DocumentBuilder
并配置,这是一个Document的建造者对象 - 使用
DocumentBuilder
获取Document
对象。这个Document
就代表了XML文档本身 - 使用Document提供的API可以获取xml节点,xml节点中的属性,xml节点中的子节点,xml节点中的文本等。
实战演示
完整代码在文章最底部
- 准备xml文件
<root>
<book verison="2.0" year="2002">
<name>三体</name>
<author>刘慈欣</author>
</book>
<book version="1.0">
<name>我不是潘金莲</name>
<author>刘震云</author>
</book>
</root>
- 按照上节介绍的步骤操作,第1步构建
DocumentBuilderFactory
对象并配置
// 使用静态方法创建工厂对象
DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
// 设置对象的配置
documentBuilderFactory.setValidating(false);
documentBuilderFactory.setCoalescing(true); // 转义CDATA
documentBuilderFactory.setIgnoringElementContentWhitespace(true);
- 第2步构建
DocumentBuilder
对象并配置;需要用到上一步的工厂来生成该对象。其实也没啥配置,就是设置了下错误处理对象。
DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
documentBuilder.setErrorHandler(new ErrorHandler() {
@Override
public void warning(SAXParseException exception) throws SAXException {
System.out.println("warn" + exception.getMessage());
}
@Override
public void error(SAXParseException exception) throws SAXException {
System.out.println("error" + exception.getMessage());
}
@Override
public void fatalError(SAXParseException exception) throws SAXException {
System.out.println("fatalError" + exception.getMessage());
}
});
- 第3步创建
Document
对象,使用上一步生成的builder对象解析指定xml文件生成该对象
Document document = documentBuilder.parse("D:/05_project/mybatis-code/src/main/java/org/apache/ibatis/amy/ixml/test.xml");
- 现在有了Document对象,就相当于有了一份XML文档,可以通过API获取到文档中的任何内容
- xml的根节点
Document#getDocumentElement
方法 - xml的其他节点
Document#getDocumentElement
方法 - xml指定名称的节点
Document#getElementsByTagName
方法 - 节点中的属性
Node#getAttributes
方法 - 节点的标签名称
Node#getNodeName
方法 - 节点子节点
Node#getChildNodes
方法 - 节点的文本内容
Node#getTextContent
方法
for (int i = 0; i < childNodes.getLength(); i++) {
Node item = childNodes.item(i);
String nodeName = item.getNodeName();
if (!"book".equals(nodeName)) {
continue;
}
System.out.println("-------------");
String textContent = item.getTextContent();
String nodeValue = item.getNodeValue();
NamedNodeMap attributes = item.getAttributes();
Optional.ofNullable(attributes).ifPresent(namedNodeMap -> {
for (int j = 0; j < attributes.getLength(); j++) {
Node attribute = attributes.item(j);
System.out.println("attributes [" + attribute.getNodeName() + "]: " + attribute.getNodeValue());
}
});
System.out.println("nodeName:" + nodeName);
System.out.println("nodeValue:" + nodeValue);
System.out.println("textContent:" + textContent);
System.out.println();
}
输出:
-------------
attributes [verison]: 2.0
attributes [year]: 2002
nodeName:book
nodeValue:null
textContent:
三体
刘慈欣
-------------
attributes [version]: 1.0
nodeName:book
nodeValue:null
textContent:
我不是潘金莲
刘震云
Process finished with exit code 0
原生JDK写XML文件
起始很多框架已经实现该功能,而且jdk原生写基本用不上,这里就简单举个例子。
public void testWriteXml() throws Exception {
String xmlString = """
<root>
<book attr1="val1"></book>
</root>
""";
//创建一个DocumentBuilderFactory的对象
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
//创建DocumentBuilder对象
DocumentBuilder db = dbf.newDocumentBuilder();
//通过DocumentBuilder对象的parser方法加载books.xml文件到当前项目下
Document document = db.parse(new StringBufferInputStream(xmlString));
//获取所有book节点的集合
NodeList bookList = document.getElementsByTagName("book");
if (bookList == null || bookList.getLength() == 0) return;
Node bookNode = bookList.item(0);
Map<String,String> bookOptions = new HashMap<>();
bookOptions.put("three body","三体");
bookOptions.put("a","三体2");
bookOptions.put("b","三体3");
//加入节点、属性等操作
for (Map.Entry<String, String> entry : bookOptions.entrySet()) {
Element optionNode = document.createElement("option");
optionNode.setTextContent(entry.getValue());
optionNode.setAttribute("name", entry.getKey());
bookNode.appendChild(optionNode);
}
//dom 转String
DOMSource source = new DOMSource(document);
StringWriter writer = new StringWriter();
Result result = new StreamResult(writer);
Transformer transformer = TransformerFactory.newInstance().newTransformer();
transformer.transform(source, result);
// 写入文档省略...(只需要把字符串利用IO流写入文档即可)
System.out.println("生成的XML文档内容是\n" + writer.toString());
}
运行输出:
生成的XML文档内容是
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<root>
<book attr1="val1"><option name="a">三体2</option><option name="b">三体3</option><option name="three body">三体</option></book>
</root>
实战演示完整代码,XML文件内容在上文已经描述不再赘述。
public void testWriteXml() throws Exception {
String xmlString = """
<root>
<book attr1="val1"></book>
</root>
""";
//创建一个DocumentBuilderFactory的对象
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
//创建DocumentBuilder对象
DocumentBuilder db = dbf.newDocumentBuilder();
//通过DocumentBuilder对象的parser方法加载books.xml文件到当前项目下
Document document = db.parse(new StringBufferInputStream(xmlString));
//获取所有book节点的集合
NodeList bookList = document.getElementsByTagName("book");
if (bookList == null || bookList.getLength() == 0) return;
Node bookNode = bookList.item(0);
Map<String,String> bookOptions = new HashMap<>();
bookOptions.put("three body","三体");
bookOptions.put("a","三体2");
bookOptions.put("b","三体3");
//加入节点、属性等操作
for (Map.Entry<String, String> entry : bookOptions.entrySet()) {
Element optionNode = document.createElement("option");
optionNode.setTextContent(entry.getValue());
optionNode.setAttribute("name", entry.getKey());
bookNode.appendChild(optionNode);
}
//dom 转String
DOMSource source = new DOMSource(document);
StringWriter writer = new StringWriter();
Result result = new StreamResult(writer);
Transformer transformer = TransformerFactory.newInstance().newTransformer();
transformer.transform(source, result);
// 写入文档省略...(只需要把字符串利用IO流写入文档即可)
System.out.println("生成的XML文档内容是\n" + writer.toString());
}