Web---XML---③Java解析XML---DOM(官方---第二方)
程序员文章站
2022-06-16 15:45:38
...
DOM-Document Object Model-文档对像模型。是w3c组织处理xml的一种方式。
•特点:
•一次将所有数据全部加载到内存中。
•对xml文档中的每一个节点都当成一个Node对像处理。包括元素、文本、属性。
•org.w3c.dom包中的Document,Element,Node。
•非常方便进行修改。
•已经集成在了JDK中,是Sun对xml操作的标准。
•缺点是当文档数据量很大时,对内存有占用很大。
DOM解析一次将所有的元素全部加载到内存中:如有以下XML文档:
<user>
<name>Jack</name>
<age>30</age>
</user>
由于DOM解析,一次性的将所有元素(包含属性和文本) 全部加载到内存中,所以不适用于解析大量的数据。
实例
XML文件
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<users>
<user id="A001">
<name>Jack</name>
<age>24</age>
</user>
<user id="A002">
<name>张三</name>
<age>22</age>
</user>
<user id="A003">
<name>李四</name>
<age>33</age>
</user>
<user id="A004">
<name>Rose</name>
<age>120</age>
</user>
<user id="B001">
<name>Mike</name>
<age>18</age>
</user>
<user id="B002">
<name>张三丰</name>
<age>28</age>
</user>
</users>
Java代码---HelloDom
import java.io.File;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import org.junit.Test;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
/*
DOM解析方式:
1)技术入口:
org.w3c.dom包中的 “Document接口”----dom树中的document对象
原来在js-dom中,docment对象是已经存在的,我们直接用就行。
现在在application-dom中,我们需要自己写代码去获取它。---调用sun公司开发的xml解析工具(包)来实现
2)sun公司开发的xml解析工具(包): javax.xml.parsers
3)dom解析方式的基本套路:
调用javax.xml.parsers包中的相应类生成
org.w3c.dom.Document接口,
然后就可以进行dom操作了。
*
*
//解析标记中的内容时,建议使用Element中的getElementByTagName()
*/
public class HelloDom {
//需求: 把users.xml中的第一个user元素中的name值输出来
@Test
public void hello() throws Exception{
//1 获取DocumentBuilderFactory
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
//2 获取DocumentBuilder
DocumentBuilder db = dbf.newDocumentBuilder();
//3 获取org.w3c.dom.Document接口--document对象
Document document = db.parse("./xml/users.xml");
//4 利用document进行dom操作 //xml文档的根元素是document的第一个孩子
Node root = document.getFirstChild(); //<users>节点
String nm = root.getNodeName();
System.out.println("nm="+nm); //users
///////////通过Node获取子节点集合的方式,不建议使用,因为存在#text即空白符节点//////////////
NodeList nodeList = root.getChildNodes();//返回<users>节点中的所有子节点
System.out.println(nodeList.item(0).getNodeName());//#text---空白符
System.out.println(nodeList.item(1).getNodeName());
System.out.println(nodeList.item(2).getNodeName());
System.out.println("------------------------");
///////////※※※建议通过Element获取子节点,可避开空白符的干扰,
//因为Element接口中有getElementsByTagName(String name)方法可以调用,而Node中没有/////////////////////////
Element eUsers = (Element) root;
NodeList nodeList2 = eUsers.getElementsByTagName("user"); //获取<users>中的所有<user>子节点---不包括空白节点
System.out.println(nodeList2.item(0).getNodeName());//#text---空白符
System.out.println(nodeList2.item(1).getNodeName());
//nodeList2中的最后一个元素
System.out.println(nodeList2.item( nodeList2.getLength()-1).getNodeName());
//把users.xml中的第一个user元素中的name值输出来
Element eUser = (Element) nodeList2.item(0);
Node eName = eUser.getElementsByTagName("name").item(0);
System.out.println(eName.getTextContent());//Jack
}
//需求: 把users.xml中的最后一个user元素中的age值输出来
@Test
public void getAgeOfLastUser() throws Exception{
DocumentBuilder db = DocumentBuilderFactory.newInstance().newDocumentBuilder();
Document dom = db.parse( new File("./xml/users.xml") );
Node root= dom.getFirstChild();//根节点--<users>
Element eUsers = (Element)root;
NodeList nodeList = eUsers.getElementsByTagName("user"); //获取所有<user>节点的集合
Element eLastUser =(Element) nodeList.item( nodeList.getLength()-1 );
Node eAge = eLastUser.getElementsByTagName("age").item(0);
String age = eAge.getTextContent();
System.out.println("age:"+age);
}
//反模式: java-dom中最好不用getElementById()的方式来获取节点,因为该方式需要使用Schema,非常麻烦!有兴趣可以参看
@Test
public void getElementByIdDemo() throws Exception{
DocumentBuilder db = DocumentBuilderFactory.newInstance().newDocumentBuilder();
Document dom = db.parse( new File("./xml/users.xml") );
Element eNode = dom.getElementById("A002");
System.out.println(eNode); //null
}
}
Java代码---DomURUD
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.junit.BeforeClass;
import org.junit.Test;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
/*
* 技术入口:
* org.w3c.dom.Document接口
* 具体实现:
* javax.xml.parsers.DocumentBuilder类的parse方法解析一个xml文件
* 返回一个org.w3c.dom.Document的实现类
*
* javax.xml.parsers.DocumentBuilder
* 需要javax.xml.parsers.DocumentBuilderFactory对象的newDocumentBuilder()方法
* javax.xml.parsers.DocumentBuilderFactory对象
* 需要javax.xml.parsers.DocumentBuilderFactory.newInstance()获取
*/
public class DomURUD {
private static Document dom ;
private static Node root;
@BeforeClass
public static void before()throws Exception {
//加载文档树
dom = DocumentBuilderFactory
.newInstance()
.newDocumentBuilder()
.parse("./xml/users.xml");
//获取dom文档树中的第一个孩子,也就是<users>元素
root = dom.getFirstChild();
}
//测试查询
@Test
public void query() {
Element eUsers = (Element) root;
NodeList colUser = eUsers.getElementsByTagName("user");
for(int i = 0; i < colUser.getLength(); i++) {
String id = ((Element)colUser.item(i)).getAttribute("id");
String name = ((Element)colUser.item(i))
.getElementsByTagName("name")
.item(0)
.getTextContent().trim();
String age = ((Element)colUser.item(i))
.getElementsByTagName("age")
.item(0)
.getTextContent().trim();
System.out.println("id:"+id+",name:"+name+","+age);
}
}
//测试修改:修改最后一个<user>
@Test
public void update() throws Exception {
Element eUsers = (Element)root;
NodeList colUser = eUsers.getElementsByTagName("user");
Element eUser = ((Element) colUser.item(colUser.getLength()-1));
Node nAge = eUser.getElementsByTagName("age").item(0);
nAge.setTextContent("20");
//改完节点只是修改了内存中的dom树数据
//要修改xml文件需要进行持久化操作
Transformer transformer = TransformerFactory
.newInstance()
.newTransformer();
transformer.transform(new DOMSource(dom), new StreamResult("./xml/users.xml"));
}
//测试添加:在users.xml中<users>元素追加一个子元素<user>
@Test
public void add() throws Exception {
//先创建<user>元素
Element eUser = dom.createElement("user");
eUser.setAttribute("id", "u007");
//创建<name>元素
Element eName = dom.createElement("name");
eName.setTextContent("李四");
//创建<age>元素
Element eAge = dom.createElement("age");
eAge.setTextContent("66");
//组装user子树
eUser.appendChild(eName);
eUser.appendChild(eAge);
//把user子树添加到users元素中
root.appendChild(eUser);
//改完节点只是修改了内存中的dom树数据
//要修改xml文件需要进行持久化操作
//一步到位
TransformerFactory
.newInstance()
.newTransformer()
.transform( new DOMSource(dom), new StreamResult("./xml/users.xml") );
}
//测试删除:删除最后一个<user>元素
@Test
public void delete() throws Exception {
Element eUsers = (Element)root;
NodeList colUser = eUsers.getElementsByTagName("user");
Node nUser = colUser.item(colUser.getLength()-1);
//找父节点删自己
nUser.getParentNode().removeChild(nUser);
//改完节点只是修改了内存中的dom树数据
//要修改xml文件需要进行持久化操作
//一步到位
TransformerFactory
.newInstance()
.newTransformer()
.transform( new DOMSource(dom), new StreamResult("./xml/users.xml") );
}
}
源码:
上一篇: Xml 解析:(sax 解析)
下一篇: 验证XML文档