一、简介。

1.xml解析技术有两种:dom和sax

2.dom:Document Object Model,即文档对象模型,是W3C组织推荐的解析XML的一种方式。

sax:Simple API for XML,不是官方标准,单它是xml社区事实上的标准。

3.XML解析器:Crimson(sun,jdk自带)、Xerces(IBM 最好的解析器)、A elfred2(dom4j),使用哪种解析器对程序员基本上没有什么影响,我们学习的是解析开发包,解析开发包调用什么样的解析器对程序员没有意义。

4.XML解析开发包:Jaxp(sun)、Jdom(不推荐使用)、dom4j(比较不错),Pull(android的sdk自带,它使用的是另外的解析方式streaming api for xml,即stax)

5.JAXP:Java API for xml Processing,jaxp是sun提供的一套xml解析API,jaxp很好地支持了dom和sax解析方式

解析XML文档使用的包名:

javax.xml
org.xml.sax
org.w3c.dom

javax.xml.parsers包中,定义了几个工厂类,程序员调用这些工程类,可以得到对xml文档进行解析的dom或者sax的解析器对

象。

6.DOM解析过程:首先将整个文档加载到内存,形成DOM树。使用dom进行解析,得到Document对象

7.使用DOM解析方式的缺点:整个文档需要全部放入内存,如果是大文件极易出现内存溢出的情况。

使用DOM解析方式的有点:操作速度快。

二、使用DOM对XML文档实现CRUD操作。

首先创建一个类:Book,该类对应着XML文档的一个节点。

 package p00.domain;

 public class Book {
public String title;
public double price;
public String id;
public String getId()
{
return id;
}
public void setId(String id)
{
this.id=id;
}
public String getTitle()
{
return title;
}
public double getPrice()
{
return price;
}
public void setTitle(String title)
{
this.title=title;
}
public void setPrice(double price)
{
this.price=price;
}
public String toString()
{
return "图书ISBN为:"+id+" 书名为:"+title+" 价格为:"+price;
} }

Book.java

得到Document对象的公共方法:

 private static Document getDocument() throws Exception {
DocumentBuilderFactory dbf=DocumentBuilderFactory.newInstance();
//获得解析器实例
DocumentBuilder db=dbf.newDocumentBuilder();
//获得Document实例
File file=new File("xmldata/books.xml");
if(!file.exists())
{
System.out.println("目标文件不存在!");
return null;
}
Document document=db.parse(file);
return document;
}

通过接受Document对象参数写入到新文件newbooks.xml的方法:

  /**
* 根据得到的Document对象将其中的内容保存到硬盘中的XML文件,完成持久化的工作。
* @param document
* @throws Exception
*/
private static void saveToAnotherPlace(Document document) throws Exception {
TransformerFactory tf=TransformerFactory.newInstance();
Transformer transformer=tf.newTransformer(); Element rootSource=document.getDocumentElement();
Source xmlSource=new DOMSource(rootSource);
Result outputTarget=new StreamResult("xmldata/books1.xml");
transformer.transform(xmlSource, outputTarget);
}

原本books.xml文档中的内容:

 <?xml version="1.0" encoding="UTF-8"?>
<books>
<book id="book1">
<title>JAVA编程思想</title>
<price>80.00</price>
</book>
<book id="book2">
<title>JAVA核心技术</title>
<price>100.00</price>
</book>
</books>

1、读取(R)

 package p01.getElementsByDomDemo;

 import java.io.File;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List; import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory; import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList; import p00.domain.Book; public class getElementsDemo {
/**
* 该类演示使用dom对xml文档的查询,包括元素节点查询和元素属性值查询。
*/
public static List<Book>list=new ArrayList<Book>();
public static void main(String[] args) throws Exception {
/**
* 得到所有的元素并保存到list中。
*/
list=getAllElementsToList();
traverse(list);//遍历集合,查看集合中的内容是否正确。
}
/**
* 该方法用于遍历集合元素。
* @param list2
*/
private static void traverse(List<Book> list2) {
System.out.println();
System.out.println("得到的集合内容为:");
Iterator<Book>it=list2.iterator();
while(it.hasNext())
{
Book book=it.next();
System.out.println(book);
}
}
public static List<Book> getAllElementsToList() throws Exception
{
List<Book>list=new ArrayList<Book>();
DocumentBuilderFactory dbf=DocumentBuilderFactory.newInstance();
DocumentBuilder db=dbf.newDocumentBuilder();
File file=new File("xmldata/books.xml");
if(!file.exists())
{
System.out.println("目标文件不存在!");
return list;
}
Document domtree=db.parse(file);
//得到根元素列表
NodeList roots=domtree.getElementsByTagName("books");
Node root=roots.item(0);
//根据根节点,遍历xml文档中的元素。
NodeList books=root.getChildNodes();
//显示结果为5本书,事实上包含了回车和换行。
// System.out.println("books节点的子节点长度为:"+books.getLength());
//遍历得到的结果集,并去除回车和换行。
for(int i=0;i<books.getLength();i++)
{
Node node=books.item(i);
String name=node.getNodeName();
if("book".equals(name))
{
Book book=new Book();
Element bookElement=(Element)node;//父接口向子接口强制转换发生异常。
String idValue=bookElement.getAttribute("id");
book.setId(idValue);
System.out.println("id属性值为:"+idValue); NodeList tp=node.getChildNodes();
//这里由于回车换行的关系,所以长度为5
// System.out.println("book节点的子节点长度为:"+tp.getLength());
for(int j=0;j<tp.getLength();j++)
{
Node node1=tp.item(j);
String nodename=node1.getNodeName();
if("title".equals(nodename))
{
String bookName=node1.getTextContent();
book.setTitle(bookName);
System.out.println("书名为:"+bookName);
}
if("price".equals(nodename))
{
String bookPrice=node1.getTextContent();
System.out.println("价格为:"+bookPrice);
double bookprice=Double.parseDouble(bookPrice);
book.setPrice(bookprice);
}
}
list.add(book);
}
else
continue;
}
return list;
} }

读取的时候应当注意的事项是调用getChildNodes方法的时候会将回车换行符作为一个子节点,应当加以判断识别才行。

2、修改(U)

 /**
* 修改XML文档的内容,将JAVA编程思想修改为Thinking in Java
* @param document
*/
private static void updateXMLContent(Document document) {
Element root=document.getDocumentElement();
NodeList books=root.getElementsByTagName("book");
for(int i=0;i<books.getLength();i++)
{
Node node=books.item(i);
Element book=(Element)node;
String id=book.getAttribute("id");
if("book1".equals(id))
{
NodeList childs=node.getChildNodes();
for(int j=0;j<childs.getLength();j++)
{
Node title=childs.item(j);
String nodeName=title.getNodeName();
if("title".equals(nodeName))
{
Element aim=(Element)title;
aim.setTextContent("Thinking in java");
}
else
continue;
}
}
else
continue;
}
}

修改后的内容:

 <?xml version="1.0" encoding="UTF-8"?><books>
<book id="book1">
<title>Thinking in java</title>
<price>80.00</price>
</book>
<book id="book2">
<title>JAVA核心技术</title>
<price>100.00</price>
</book>
</books>

3、删除(D)

 /**
* 删除指定元素的方法,要求:删除id值为002的元素。
* @param document
*/
private static void removeOldNodeFromXML(Document document) { Element root=document.getDocumentElement();
NodeList books=root.getElementsByTagName("book");
for(int i=0;i<books.getLength();i++)
{
Node node=books.item(i);
Element book=(Element)node;
String id=book.getAttribute("id");
if("book2".equals(id))
{
Node parent=node.getParentNode();
parent.removeChild(node);
}
else
continue;
} }

删除后内容:

 <?xml version="1.0" encoding="UTF-8"?><books>
<book id="book1">
<title>JAVA编程思想</title>
<price>80.00</price>
</book> </books>

4、添加(C)

  /**
* 添加新元素的方法。
* :添加一个新节点,节点要求:id为book3,title为计算机网络,price为1.0
* @param document
*/
private static void addNewNodeToXML(Document document) {
Element root=document.getDocumentElement();
Element book=document.createElement("book");
book.setAttribute("id", "book3");
Element title=document.createElement("title");
Element price=document.createElement("price");
title.setTextContent("计算机网络");
price.setTextContent("1.0");
book.appendChild(title);
book.appendChild(price);
root.appendChild(book);
}

添加后内容:

 <?xml version="1.0" encoding="UTF-8"?><books>
<book id="book1">
<title>JAVA编程思想</title>
<price>80.00</price>
</book>
<book id="book2">
<title>JAVA核心技术</title>
<price>100.00</price>
</book>
<book id="book3"><title>计算机网络</title><price>1.0</price></book></books>

注意使用这种方式添加的元素没有格式上的缩进。

5、完整代码。

 package p01.getElementsByDomDemo;

 import java.io.File;

 import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.Result;
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult; import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList; public class CUDDemo { public static void main(String[] args) throws Exception {
Document document=getDocument();
//修改操作:把id为book1的书籍title的值改为Thinking in java
// updateXMLContent(document); //添加新元素操作
// addNewNodeToXML(document); //删除指定元素的方法。
// removeOldNodeFromXML(document);
//作为一个独立的方法将得到的document对象中的内容写入到硬盘中的文件。
saveToAnotherPlace(document);
}
/**
* 删除指定元素的方法,要求:删除id值为002的元素。
* @param document
*/
private static void removeOldNodeFromXML(Document document) { Element root=document.getDocumentElement();
NodeList books=root.getElementsByTagName("book");
for(int i=0;i<books.getLength();i++)
{
Node node=books.item(i);
Element book=(Element)node;
String id=book.getAttribute("id");
if("book2".equals(id))
{
Node parent=node.getParentNode();
parent.removeChild(node);
}
else
continue;
} }
/**
* 添加新元素的方法。
* :添加一个新节点,节点要求:id为book3,title为计算机网络,price为1.0
* @param document
*/
private static void addNewNodeToXML(Document document) {
Element root=document.getDocumentElement();
Element book=document.createElement("book");
book.setAttribute("id", "book3");
Element title=document.createElement("title");
Element price=document.createElement("price");
title.setTextContent("计算机网络");
price.setTextContent("1.0");
book.appendChild(title);
book.appendChild(price);
root.appendChild(book);
} /**
* 修改XML文档的内容,将JAVA编程思想修改为Thinking in Java
* @param document
*/
private static void updateXMLContent(Document document) {
Element root=document.getDocumentElement();
NodeList books=root.getElementsByTagName("book");
for(int i=0;i<books.getLength();i++)
{
Node node=books.item(i);
Element book=(Element)node;
String id=book.getAttribute("id");
if("book1".equals(id))
{
NodeList childs=node.getChildNodes();
for(int j=0;j<childs.getLength();j++)
{
Node title=childs.item(j);
String nodeName=title.getNodeName();
if("title".equals(nodeName))
{
Element aim=(Element)title;
aim.setTextContent("Thinking in java");
}
else
continue;
}
}
else
continue;
}
} /**
* 根据得到的Document对象将其中的内容保存到硬盘中的XML文件,完成持久化的工作。
* @param document
* @throws Exception
*/
private static void saveToAnotherPlace(Document document) throws Exception {
TransformerFactory tf=TransformerFactory.newInstance();
Transformer transformer=tf.newTransformer(); Element rootSource=document.getDocumentElement();
Source xmlSource=new DOMSource(rootSource);
Result outputTarget=new StreamResult("xmldata/books1.xml");
transformer.transform(xmlSource, outputTarget);
} /**
* 得到Document对象的方法。
* @return
* @throws Exception
*/
private static Document getDocument() throws Exception {
DocumentBuilderFactory dbf=DocumentBuilderFactory.newInstance();
//获得解析器实例
DocumentBuilder db=dbf.newDocumentBuilder();
//获得Document实例
File file=new File("xmldata/books.xml");
if(!file.exists())
{
System.out.println("目标文件不存在!");
return null;
}
Document document=db.parse(file);
return document;
} }

三、SAX

使用该解析技术只能实现对XML文档的读取操作。使用这种方式的优点就是它的解析方式为“逐行读取”,并非将XML文档一次性加载进内存,这样就能够避免内存溢出的情况了,该解析方式是dom4j的解析方式。

注意DefaultHandler类,该类实现了某些处理xml文档必须的接口,但是均没有具体的方法,也就是说是空方法,如果想要解析xml文档,需要覆写该方法。

 package p02.readElementsBySaxDemo;

 import java.io.File;

 import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory; import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler; /**
* 该类的功能是通过Sax技术实现对xml文档的查找操作。
* 使用SAX技术不能实现对XML文档的增删改操作。
* @author kdyzm
*
*/
public class ReadXMLBySax { public static void main(String[] args) throws Exception, SAXException {
SAXParserFactory spf=SAXParserFactory.newInstance();
SAXParser sp=spf.newSAXParser();
File file=new File("xmldata/books.xml");
MyHandler mh=new MyHandler();
sp.parse(file, mh);
} } /**
* 该类重写了默认处理类中的部分方法。
* @author kdyzm
*
*/
class MyHandler extends DefaultHandler
{ //文档开始的时候触发该事件
@Override
public void startDocument() throws SAXException {
System.out.println("开始解析文档!");
super.startDocument();
} //文档结束的时候触发该事件
@Override
public void endDocument() throws SAXException {
System.out.println("解析文档结束!");
super.endDocument();
} //当开始解析一个元素的时候触发该事件
@Override
public void startElement(String uri, String localName, String qName,
Attributes attributes) throws SAXException {
System.out.println("开始解析元素:"+qName+" 属性id的值是:"+attributes.getValue("id"));
super.startElement(uri, localName, qName, attributes);
} //解析完成一个元素的时候触发该事件
@Override
public void endElement(String uri, String localName, String qName)
throws SAXException {
super.endElement(uri, localName, qName);
System.out.println("解析元素结束:"+qName);
} //遇到字符串的时候触发该事件。
@Override
public void characters(char[] ch, int start, int length)
throws SAXException {
System.out.println("解析得到的字符串是:"+new String(ch,start,length));
super.characters(ch, start, length);
} }

输出:

开始解析文档!
开始解析元素:books 属性id的值是:null
解析得到的字符串是: 开始解析元素:book 属性id的值是:book1
解析得到的字符串是: 开始解析元素:title 属性id的值是:null
解析得到的字符串是:JAVA编程思想
解析元素结束:title
解析得到的字符串是: 开始解析元素:price 属性id的值是:null
解析得到的字符串是:80.00
解析元素结束:price
解析得到的字符串是: 解析元素结束:book
解析得到的字符串是: 开始解析元素:book 属性id的值是:book2
解析得到的字符串是: 开始解析元素:title 属性id的值是:null
解析得到的字符串是:JAVA核心技术
解析元素结束:title
解析得到的字符串是: 开始解析元素:price 属性id的值是:null
解析得到的字符串是:100.00
解析元素结束:price
解析得到的字符串是: 解析元素结束:book
解析得到的字符串是: 解析元素结束:books
解析文档结束!

四、使用dom4j解析包快速解析XML文档,实现CRUD操作。

【JAVA解析XML文件实现CRUD操作】的更多相关文章

  1. 【JAVA使用XPath、DOM4J解析XML文件,实现对XML文件的CRUD操作】

    一.简介 1.使用XPath可以快速精确定位指定的节点,以实现对XML文件的CRUD操作. 2.去网上下载一个“XPath帮助文档”,以便于查看语法等详细信息,最好是那种有很多实例的那种. 3.学习X ...

  2. java解析xml文件并输出

    使用java解析xml文件,通过dom4j,代码运行前需先导入dom4j架包. ParseXml类代码如下: import java.io.File; import java.util.ArrayLi ...

  3. 使用Java解析XML文件或XML字符串的例子

    转: 使用Java解析XML文件或XML字符串的例子 2017年09月16日 11:36:18 inter_peng 阅读数:4561 标签: JavaXML-Parserdom4j 更多 个人分类: ...

  4. Java解析xml文件遇到特殊符号&会出现异常的解决方案

    文/朱季谦 在一次Java解析xml文件的开发过程中,使用SAX解析时,出现了这样一个异常信息: Error on line 60 of document : 对实体 "xxx" ...

  5. java解析XML文件

    dom4j是一个Java的XML API,类似于jdom,用来读写XML文件的.dom4j是一个非常非常优秀的Java XML API,具有性能优异.功能强大和极端易用使用的特点,同时它也是一个开放源 ...

  6. JAVA解析XML文件(DOM,SAX,JDOM,DOM4j附代码实现)

    1.解析XML主要有四种方式 1.DOM方式解析XML(与平台无关,JAVA提供,一次性加载XML文件内容,形成树结构,不适用于大文件) 2.SAX方式解析XML(基于事件驱动,逐条解析,适用于只处理 ...

  7. java解析XML文件四种方法之引入源文件

    1.DOM解析(官方) try { DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();         Documen ...

  8. Java解析XML文件的方式

    在项目里,我们往往会把一些配置信息放到xml文件里,或者各部门间会通过xml文件来交换业务数据,所以有时候我们会遇到“解析xml文件”的需求.一般来讲,有基于DOM树和SAX的两种解析xml文件的方式 ...

  9. java 解析xml文件案例

    package xmlTest; import javax.xml.parsers.*; import org.w3c.dom.*; public class GetXml { public stat ...

随机推荐

  1. POJ 1273 网络流(最大流)模板

    http://poj.org/problem?id=1273 这道题很值得反思,弄了一下午,交上去先是一直编译错误,而在本地运行没有问题, 原因可能是oj的编译器版本老旧不支持这样的写法 G[from ...

  2. PHP输出控制(Output Control)函数

    ob_start 此函数将打开输出缓冲.当输出缓冲激活后,脚本将不会输出内容(除http标头外),相反需要输出的内容被存储在内部缓冲区中. 内部缓冲区的内容可以用 ob_get_contents() ...

  3. HTTP协议详解篇(待续)

    1.工作流程 HTTP通信机制是在一次完整的HTTP通信过程中,Web浏览器与Web服务器之间将完成下列7个步骤: (1)建立TCP连接 在HTTP工作开始之前,Web浏览器首先要通过网络与Web服务 ...

  4. 2.2---找链表倒数第K个结点

    答案,注意,一种是递归,另一种是迭代,那么巧妙利用双指针: 迭代: public static LinkedListNode nthToLast(LinkedListNode head, int n) ...

  5. python 模块之间的变量共享

    才疏学浅,只知道两种方式: 1. 通过__builtin__实现: builtin1.py import __builtin__ __builtin__.some_global_var_among_m ...

  6. devstack meaning of: n-cond, n-novnc and n-xvnc

    devstack has shortened names for a number of services, e.g. g-api = glance api g-reg = glance regist ...

  7. C#中委托演变的的三个阶段

    命名函数 匿名方法 lambda表达式 委托是一种可以把引用存储为函数的类型,定义了委托后,就可以声明该委托类型的变量,接着把这个变量初始化为与委托有相同返回类型和参数列表的函数引用,之后就可以使用委 ...

  8. Clone Graph

    Clone an undirected graph. Each node in the graph contains a label and a list of its neighbors. OJ's ...

  9. centos7 安装mysql5.7.11注意事项

    centos7通过yum install mysql默认安装的是mariadb.至于为什么默认安装mariadb以及mariadb和mysql的区别,网上有很多说明.这里不再阐述,下面介绍下怎么另行下 ...

  10. Java for LeetCode 221 Maximal Square

    Given a 2D binary matrix filled with 0's and 1's, find the largest square containing all 1's and ret ...