使用DOM和DOM4J对XML文件解析
本章节的源代码位于gitee上,想要下载的请点击XML解析
如果有对xml不了解的朋友,可以跳转到XML界面,该界面详细的谈了XML的定义、使用等。这里我们就直接提取xml中的数据即可。
首先我们在项目中创建一个person.xml文件,文件中添加上相关的数据。
<?xml version="1.0" encoding="UTF-8" ?>
<persons>
<person>
<name>张三</name>
<age>18</age>
<sex>男</sex>
<birthday>
<year>1998</year>
<month>11</month>
<day>11</day>
</birthday>
</person>
<person>
<name>李四</name>
<age>19</age>
</person>
</persons>
DOM
1、DOM的全称是Document Object Model,也即文档对象模型。在应用程序中,基于DOM的XML分析器将一个XML文档转换成一个对象模型的集合(通常称DOM树),应用程序正是通过对这个对象模型的操作,来实现对XML文档数据的操作。通过DOM接口,应用程序可以在任何时候访问XML文档中的任何一部分数据,因此,这种利用DOM接口的机制也被称作随机访问机制。
2、适用范围:小型 XML 文件解析、需要全解析或者大部分解析 XML、需要修改 XML 树内容以生成自己的对象模型。
解析需要的数据:
public class DOMDemo {
public static void main(String[] args) {
try {
File f = new File("general/resources/person.xml");
//获取DocumentBuilderFactory
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
//通过DocumentBuilder工厂产生一个DocumentBuilder
DocumentBuilder builder = factory.newDocumentBuilder();
//利用DocumentBuilder产生Document
Document doc = builder.parse(f);
NodeList nl = doc.getElementsByTagName("person");
for (int i = 0; i < nl.getLength(); i++) {
System.out.println("name:"+ doc.getElementsByTagName("name").item(i).getFirstChild().getNodeValue());
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-PcnDok2x-1603593132407)(C:\Users\C3H2\AppData\Roaming\Typora\typora-user-images\image-20201024154547142.png)]
上面我们只解析了部分数据出来,如果我们想将全部数据都解析出来应该如何操作呢?
public class DOMDemo {
public static void main(String[] args) {
try {
//得到DOM解析器的工厂实例
DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
//从DOM工厂中获得DOM解析器
DocumentBuilder dbBuilder = dbFactory.newDocumentBuilder();
//把要解析的xml文档读入DOM解析器
Document doc = dbBuilder.parse("general/resources/person.xml");
System.out.println("处理该文档的DomImplementation对象 = " + doc.getImplementation());
//得到文档名称为Student的元素的节点列表
NodeList nList = doc.getElementsByTagName("person");
//遍历该集合,显示结合中的元素及其子元素的名字
for (int i = 0; i < nList.getLength(); i++) {
Element node = (Element) nList.item(i);
System.out.println("name: " + node.getElementsByTagName("name").item(0).getFirstChild().getNodeValue());
System.out.println("age: " + node.getElementsByTagName("age").item(0).getFirstChild().getNodeValue());
if(node.getElementsByTagName("sex").item(0)!=null){
System.out.println("sex: " + node.getElementsByTagName("sex").item(0).getFirstChild().getNodeValue());
}
NodeList birthdayNode = node.getElementsByTagName("birthday");
for (int j = 0; j < birthdayNode.getLength(); j++) {
Element birthdayElement = (Element) birthdayNode.item(i);
System.out.print("birthday: year: " + birthdayElement.getElementsByTagName("year").item(0).getFirstChild().getNodeValue());
System.out.print(" month: " + birthdayElement.getElementsByTagName("month").item(0).getFirstChild().getNodeValue());
System.out.print(" day: " + birthdayElement.getElementsByTagName("day").item(0).getFirstChild().getNodeValue()+"\n");
}
}
} catch(Exception e) {
e.printStackTrace();
}
}
}
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Km2V5LNo-1603593132414)(C:\Users\C3H2\AppData\Roaming\Typora\typora-user-images\image-20201024155934545.png)]
DOM4J
dom4j是一个简单的开源库,用于处理XML、 XPath和XSLT,它基于Java平台,使用Java的集合框架,全面集成了DOM,SAX和JAXP。dom4j是目前在xml解析方面是最优秀的(Hibernate、Sun的JAXM也都使用dom4j来解析XML),它合并了许多超出基本 XML 文档表示的功能,包括集成的 XPath 支持、XML Schema 支持以及用于大文档或流化文档的基于事件的处理。
需要注意的是使用DOM4J是需要从外部引入dom4j的jar包的,这个可以直接到Maven仓库去下载。如果使用的是Maven那么就只需要将下面的那串代码复制到pom.xml中即可。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-eI19xe8j-1603593132417)(C:\Users\C3H2\AppData\Roaming\Typora\typora-user-images\image-20201024162342002.png)]
public class DOM4JDemo {
public static void main(String[] args) throws Exception{
SAXReader saxReader = new SAXReader();
Document document = saxReader.read(new File("general/resources/person.xml"));
// 获取根元素
Element root = document.getRootElement();
System.out.println("根: " + root.getName());
// 获取所有子元素
List<Element> childList = root.elements();//root.elements("person");//获取名称为person的子元素
System.out.println("一级子元素个数: " + childList.size());
}
}
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-yk0YiZwT-1603593132422)(C:\Users\C3H2\AppData\Roaming\Typora\typora-user-images\image-20201024220739787.png)]
上述只是单纯的将根和一级子元素获取到了,但是对于其中的只应该如何获取呢?
public class DOM4JDemo {
public static void main(String[] args) throws Exception{
SAXReader saxReader = new SAXReader();
Document document = saxReader.read(new File("general/resources/person.xml"));
// 获取根元素
Element root = document.getRootElement();
System.out.println("根: " + root.getName());
// 获取所有子元素
List<Element> childList = root.elements();//root.elements("persons");//获取名称为person的子元素
System.out.println("一级子元素个数: " + childList.size());
// 得到p1
List<Element> list = root.elements("person");
// 遍历list
for (Element element : list) {
List<Element> listElement = element.elements();
for (Element element1 : listElement){
if(element1.getName().equalsIgnoreCase("birthday")){
List<Element> list1 = element1.elements();
System.out.print("birthday: ");
for(Element element2 : list1){
System.out.print(element2.getText()+"-");
}
System.out.println();
} else {
System.out.println(element1.getName() + ": " + element1.getText());
}
}
}
}
}
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-nSKMFVlS-1603593132426)(C:\Users\C3H2\AppData\Roaming\Typora\typora-user-images\image-20201025102717400.png)]