使用 XML 工具: dom4j
小于 1 分钟
开源三方件,对原生 java xml 读写做了封装。
基本用法
https://github.com/LawssssCat/blog/tree/master/code/demo-java-xml/n02-dom4j-usage/test/java/org/example/读
XML 文件
<?xml version="1.0" encoding="utf-8" ?>
<my-content>
<web-site>http://www.example.org</web-site>
<owner>steven</owner>
<description>原生 java xml 操作测试消息</description>
<posts>
<!-- 我是注释 -->
<post id="P001">
<title>文章标题01</title>
<content>hello world 01!</content>
</post>
<post id="P002">
<title>文章标题02</title>
<content>hello world 02!</content>
</post>
</posts>
</my-content>
测试用例
package org.example;
import lombok.extern.slf4j.Slf4j;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
@Slf4j
public class XmlDom4jReadTest {
Document read;
@BeforeEach
void beforeEach() {
SAXReader saxReader = new SAXReader();
try {
read = saxReader.read(getClass().getResource("/message001.xml"));
} catch (DocumentException e) {
throw new RuntimeException(e);
}
}
@Test
void test_elements() {
AtomicInteger i = new AtomicInteger(0);
printElements(1, read.getRootElement(), i);
Assertions.assertEquals(11, i.get());
}
private void printElements(int deep, Element e, AtomicInteger i) {
i.incrementAndGet();
log.info(String.format("%"+deep+"s%s", "", e.getQualifiedName()));
for (Element c : e.elements()) {
printElements(deep+1, c, i);
}
}
@Test
void test_getRootElement() {
Element rootElement = read.getRootElement();
Assertions.assertEquals("my-content", rootElement.getQualifiedName());
Assertions.assertEquals(2, rootElement.element("posts").elements().size());
Assertions.assertArrayEquals(new String[] {"P001", "P002"}, rootElement.element("posts").elements().stream().map(e -> e.attribute("id").getValue()).toArray());
}
@Test
void test_nodeIterator() {
int countContentElement = 0;
int countPostElement = 0;
List<String> contentElementQNameList = new ArrayList<>();
List<String> postElementIdList = new ArrayList<>();
// test
Element rootElement = read.getRootElement();
Iterator<Element> contentIterator = rootElement.elementIterator();
while (contentIterator.hasNext()) {
countContentElement++;
Element contentElement = contentIterator.next();
System.out.println("contentElement = " + contentElement);
contentElementQNameList.add(contentElement.getQualifiedName());
if("posts".equals(contentElement.getQualifiedName())) {
Iterator<Element> postIterator = contentElement.elementIterator();
while (postIterator.hasNext()) {
countPostElement++;
Element post = postIterator.next();
System.out.println("postElement = " + post);
postElementIdList.add(post.attributeValue("id"));
}
}
}
Assertions.assertEquals(4, countContentElement);
Assertions.assertEquals(2, countPostElement);
Assertions.assertArrayEquals(new String[] {"web-site", "owner", "description", "posts"}, contentElementQNameList.toArray());
Assertions.assertArrayEquals(new String[] {"P001", "P002"}, postElementIdList.toArray());
}
@Test
void test_parseText() throws DocumentException {
Document document = DocumentHelper.parseText(read.asXML());
Assertions.assertEquals("my-content", document.getRootElement().getName());
}
}
写
测试用例
package org.example;
import org.dom4j.*;
import org.dom4j.dom.DOMAttribute;
import org.dom4j.io.XMLWriter;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import utils.IOUtils;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
public class XmlDom4jWriteTest {
@Test
void test() throws IOException {
Document document = DocumentHelper.createDocument();
Element content = document.addElement("content");
Element owner = content.addElement("owner");
owner.setText("steven");
Element posts = content.addElement("posts");
for (int i = 0; i < 2; i++) {
Element post = posts.addElement("post");
List<Attribute> attributes = Collections.singletonList(new DOMAttribute(QName.get("id"), "P00" + i));
post.setAttributes(attributes);
}
// write
File file = new File(Objects.requireNonNull(getClass().getResource("/")).getFile(), getClass().getName() + ".xml");
try (FileOutputStream fileOutputStream = new FileOutputStream(file)) {
XMLWriter xmlWriter = new XMLWriter(fileOutputStream);
xmlWriter.write(content);
}
// validate
Assertions.assertTrue(file.exists());
Assertions.assertEquals("<content><owner>steven</owner><posts><post id=\"P000\"/><post id=\"P001\"/></posts></content>",
IOUtils.readFile(file));
}
}
namespace
XML 文件
<?xml version="1.0" encoding="utf-8" ?>
<xxx:my-content xmlns:xxx="http://example.org/xxx">
<xxx:web-site>http://www.example.org</xxx:web-site>
<owner>steven</owner>
<description>原生 java xml 操作测试消息</description>
<posts>
<!-- 我是注释 -->
<post id="P001">
<title>文章标题01</title>
<content>hello world 01!</content>
</post>
<post id="P002">
<title>文章标题02</title>
<content>hello world 02!</content>
</post>
</posts>
</xxx:my-content>
测试用例
package org.example;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
public class XmlDom4jReadNamespaceTest {
Document read;
@BeforeEach
void beforeEach() {
SAXReader saxReader = new SAXReader();
try {
read = saxReader.read(getClass().getResource("/message002.xml"));
} catch (DocumentException e) {
throw new RuntimeException(e);
}
}
@Test
void test_getName_and_getQualifiedName() {
Element rootElement = read.getRootElement();
Assertions.assertEquals("my-content", rootElement.getName());
Assertions.assertEquals("xxx:my-content", rootElement.getQualifiedName());
Assertions.assertEquals("xxx", rootElement.getNamespacePrefix());
Assertions.assertEquals("http://example.org/xxx", rootElement.getNamespaceURI());
Assertions.assertNull(rootElement.element("xxx:web-site"));
Element webSite = rootElement.element("web-site");
Assertions.assertNotNull(webSite);
Assertions.assertEquals("web-site", webSite.getName());
Assertions.assertEquals("xxx:web-site", webSite.getQualifiedName());
Assertions.assertEquals("xxx", webSite.getNamespacePrefix());
Assertions.assertEquals("http://example.org/xxx", webSite.getNamespaceURI());
}
@Test
void test_XPath() {
Element rootElement = read.getRootElement();
Assertions.assertNull(rootElement.selectSingleNode("web-site"));
Assertions.assertNotNull(rootElement.selectSingleNode("xxx:web-site"));
}
}
XPath
采用 xpath
查找需要引入 jaxen-xx-xx.jar
,否则会报 java.lang.NoClassDefFoundError: org/jaxen/JaxenException
异常。
<dependency>
<groupId>jaxen</groupId>
<artifactId>jaxen</artifactId>
</dependency>
package org.example;
import lombok.extern.slf4j.Slf4j;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.Node;
import org.dom4j.io.SAXReader;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import java.util.List;
@Slf4j
public class XmlDom4jXPathTest {
Document read;
@BeforeEach
void beforeEach() {
SAXReader saxReader = new SAXReader();
try {
read = saxReader.read(getClass().getResource("/message001.xml"));
} catch (DocumentException e) {
throw new RuntimeException(e);
}
}
@Test
void test_selectNodes() {
List<Node> nodes = read.selectNodes("//posts/*");
log.info("{}", nodes);
Assertions.assertEquals(2, nodes.size());
nodes.forEach(n -> {
Assertions.assertInstanceOf(Element.class, n);
Assertions.assertEquals("post", n.getName());
});
}
@Test
void test_selectSingleNode() {
Node node = read.selectSingleNode("//posts/*[2]");
Assertions.assertInstanceOf(Element.class, node);
Assertions.assertEquals("post", node.getName());
Element e = (Element) node;
Assertions.assertEquals("P002", e.attribute("id").getValue());
Assertions.assertEquals(2, e.elements().size());
}
@Test
void test_Predicates() {
Element node = (Element) read.selectSingleNode("//posts/*[@id='P002']");
log.info("{}", node);
Assertions.assertEquals("post", node.getQualifiedName());
Assertions.assertEquals("文章标题02", node.element("title").getStringValue());
Assertions.assertEquals("hello world 02!", node.element("content").getStringValue());
}
}