JAXP解析XML文件之DOM解析
常用的XML解析器
1) JAXP
2) DOM4J
3) JDOM
4) Digester
什么是JAXP
JAXP 开发包是J2SE的一部分,它由javax.xml、org.w3c.dom 、org.xml.sax 包及其子包组成在javax.xml.parsers 包中,定义了几个工厂类,程序员调用这些工厂类,可以得到对xml文档进行解析的 DOM 或 SAX 的解析器对象。
JAXP核心API
DocumentBuilderFactory:是一个抽象工厂类,它不能直接实例化,但该类提供了一个newInstance方法 ,这个方法会根据本地平台默认安装的解析器,自动创建一个工厂的对象并返回。调用工厂对象的newDocumentBuilder方法得到 DOM 解析器对象(DocumentBuilder)。
DocumentBuilder:用于从XML文档中获取DOM文档实例。调用 DocumentBuilder的 parse() 方法解析 XML 文档,得到代表整个文档的 Document 对象,这样可以利用DOM特性对整个XML文档进行操作了。
Document:代表了一个XML文档的树模型。以后所有的对XML文档的操作,都与解析器无关,直接在这个Document对象上进行操作就可以了。
Node:DOM解析器在解析XML文档时,会把文档中的所有元素,按照其出现的层次关系,解析成一个个Node对象(节点)。
在DOM中,节点之间关系如下:
Ø 位于一个节点之上的节点是该节点的父节点(parent)
Ø 一个节点之下的节点是该节点的子节点(children)
Ø 同一层次,具有相同父节点的节点是兄弟节点(sibling)
Ø 一个节点的下一个层次的节点集合是节点后代(descendant)
Ø 父、祖父节点及所有位于节点上面的,都是节点的祖先(ancestor)
节点(Node)可以是元素节点(Element)、属性节点(Attr)、文本节点(Text)、实体节点(Entity)等等。Node对象提供了一系列常量来代表结点的类型,当开发人员获得某个Node类型后,就可以把Node节点转换成相应的节点对象(Node的子类对象),以便于调用其特有的方法。
Node对象提供了相应的方法去获得它的父结点或子结点。编程人员通过这些方法就可以读取整个XML文档的内容、或添加、修改、删除XML文档的内容了。
Transformer:用于把代表XML文件的Document对象转换为某种格式后进行输出,例如把xml文件应用样式表后转成一个html文档。利用这个对象,当然也可以把Document对象又重新写入到一个XML文件中。
Transformer类通过transform方法完成转换操作,该方法接收一个源和一个目的地。我们可以通过:
javax.xml.transform.dom.DOMSource类来关联要转换的document对象,
用javax.xml.transform.stream.StreamResult 对象来表示数据的目的地。
Transformer对象通过TransformerFactory获得。
体验JAXP
Jaxp.xml文件
<?xml version="1.0" encoding="UTF-8"?> <department> <user no="001"> <name>郭靖</name> <six>男</six> <age>25</age> </user> <user no="002"> <name>黄蓉</name> <six>女</six> <age>20</age> </user> </department>
解析代码
package com.rabbit.jaxp; import org.junit.Test; import org.w3c.dom.*; import org.xml.sax.SAXException; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; import javax.xml.transform.Transformer; import javax.xml.transform.TransformerConfigurationException; import javax.xml.transform.TransformerException; import javax.xml.transform.TransformerFactory; import javax.xml.transform.dom.DOMSource; import javax.xml.transform.stream.StreamResult; import java.io.FileOutputStream; import java.io.IOException; /** * jaxp解析dom树 * Created by HASEE on 2018/5/3. */ public class JaxpDomDemo { @Test public void deleteElem() throws Exception { //创建DocumentBuilderFactory对象 DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); //创建DocumentBuilder对象 DocumentBuilder builder = factory.newDocumentBuilder(); //通过DocumentBuilder解析XML文档,创建Document对象 //注意这个路径是class下的文件路径,不是源文件的路径,所以修改的是编译后的路径 Document doc = builder.parse(this.getClass().getResource("/jaxp.xml").getPath()); //找到需要删除的节点 Element elem = (Element)doc.getElementsByTagName("age").item(1); //利用父节点删除 elem.getParentNode().removeChild(elem); //刷新内存的数据到磁盘 TransformerFactory tFactory = TransformerFactory.newInstance(); Transformer former = tFactory.newTransformer(); former.transform(new DOMSource(doc), new StreamResult(new FileOutputStream(this.getClass().getResource("/jaxp.xml").getPath()))); } @Test public void updateAttr() throws Exception { //创建DocumentBuilderFactory对象 DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); //创建DocumentBuilder对象 DocumentBuilder builder = factory.newDocumentBuilder(); //通过DocumentBuilder解析XML文档,创建Document对象 //注意这个路径是class下的文件路径,不是源文件的路径,所以修改的是编译后的路径 Document doc = builder.parse(this.getClass().getResource("/jaxp.xml").getPath()); //获取要挂载的元素 Element elem = (Element)doc.getElementsByTagName("user").item(0); elem.setAttribute("code", "100"); //刷新内存的数据到磁盘 TransformerFactory tFactory = TransformerFactory.newInstance(); Transformer former = tFactory.newTransformer(); former.transform(new DOMSource(doc), new StreamResult(new FileOutputStream(this.getClass().getResource("/jaxp.xml").getPath()))); } //动态创建元素并挂载 @Test public void updateElem() throws Exception { //创建DocumentBuilderFactory对象 DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); //创建DocumentBuilder对象 DocumentBuilder builder = factory.newDocumentBuilder(); //通过DocumentBuilder解析XML文档,创建Document对象 //注意这个路径是class下的文件路径,不是源文件的路径,所以修改的是编译后的路径 Document doc = builder.parse(this.getClass().getResource("/jaxp.xml").getPath()); //获取要挂载的元素 Element elem = (Element)doc.getElementsByTagName("age").item(0); elem.setTextContent("100"); //刷新内存的数据到磁盘 TransformerFactory tFactory = TransformerFactory.newInstance(); Transformer former = tFactory.newTransformer(); former.transform(new DOMSource(doc), new StreamResult(new FileOutputStream(this.getClass().getResource("/jaxp.xml").getPath()))); } @Test public void createAttr() throws Exception { //创建DocumentBuilderFactory对象 DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); //创建DocumentBuilder对象 DocumentBuilder builder = factory.newDocumentBuilder(); //通过DocumentBuilder解析XML文档,创建Document对象 //注意这个路径是class下的文件路径,不是源文件的路径,所以修改的是编译后的路径 Document doc = builder.parse(this.getClass().getResource("/jaxp.xml").getPath()); //获取要挂载的元素 Element elem = (Element)doc.getElementsByTagName("user").item(0); elem.setAttribute("code", "001"); //刷新内存的数据到磁盘 TransformerFactory tFactory = TransformerFactory.newInstance(); Transformer former = tFactory.newTransformer(); former.transform(new DOMSource(doc), new StreamResult(new FileOutputStream(this.getClass().getResource("/jaxp.xml").getPath()))); } //动态创建元素并挂载 @Test public void createElem() throws Exception { //创建DocumentBuilderFactory对象 DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); //创建DocumentBuilder对象 DocumentBuilder builder = factory.newDocumentBuilder(); //通过DocumentBuilder解析XML文档,创建Document对象 //注意这个路径是class下的文件路径,不是源文件的路径,所以修改的是编译后的路径 Document doc = builder.parse(this.getClass().getResource("/jaxp.xml").getPath()); //创建元素 Element like = doc.createElement("like"); like.setTextContent("游泳"); //获取要挂载的元素 Element elem = (Element)doc.getElementsByTagName("user").item(0); //挂载 elem.appendChild(like); //刷新内存的数据到磁盘 TransformerFactory tFactory = TransformerFactory.newInstance(); Transformer former = tFactory.newTransformer(); former.transform(new DOMSource(doc), new StreamResult(new FileOutputStream(this.getClass().getResource("/jaxp.xml").getPath()))); } //初步体验 @Test public void test() throws ParserConfigurationException, IOException, SAXException { //创建DocumentBuilderFactory对象 DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); //创建DocumentBuilder对象 DocumentBuilder builder = factory.newDocumentBuilder(); //通过DocumentBuilder解析XML文档,创建Document对象 Document doc = builder.parse(this.getClass().getResource("/jaxp.xml").getPath()); //获取XML文档的根节点 Node root = doc.getChildNodes().item(0); parseChildNode(root); } private void parseChildNode(Node root) { //打印节点名称 System.out.println(root.getNodeName()); NodeList cList = root.getChildNodes(); for(int i=0;i<cList.getLength();i++){ Node cNode = cList.item(i); parseChildNode(cNode); } } }