一、简介。

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. 前端之js的常用用法

    js生成标签 // 将标签添加到i1里面 var tag = document.createElement('input'); tag.setAttribute('type', 'text'); ta ...

  2. c# Dictionary的遍历和排序

    c# Dictionary的遍历和排序 c#遍历的两种方式 for和foreach for: 需要指定首位数据.末尾数据.数据长度: for遍历语句中可以改变数据的值: 遍历规则可以自定义,灵活性较高 ...

  3. trap

    http://blog.csdn.net/elbort/article/details/8525599 http://mywiki.wooledge.org/SignalTrap

  4. mysql grant ,User,revoke

    mysql的权限一直都都是很关心的重点,我知道的也只是很少的一部分,对于每个数据库我习惯创建一个一个用户,该用户只对自己从属的数据库产生进行操作,在一部分的程度上可以保护自己的数据库, 比如我有一个数 ...

  5. poj1155

    题意:给定一个树形图,节点数量3000.叶子节点是用户,每个用户如果能看上电视会交一定的电视费.看上电视的条件是从根到该用户的路径全部被修好,修每条边有一个费用.在不亏损(用户交钱总额>=修路总 ...

  6. Java集合中Map接口的使用方法

    Map接口 Map提供了一种映射关系,其中的元素是以键值对(key-value)的形式存储的,能够实现根据key快速查找value: Map中的键值对以Entry类型的对象实例形式存在: 建(key值 ...

  7. Debian 配置apt-get源

    1.配置apt-get源 cp  /etc/apt/sources.list  /etc/apt/sources.listbak   #备份原有配置文件       nano  /etc/apt/so ...

  8. 点击按钮出现60秒倒计时js代码

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  9. IOS- DocumentInteraction Controllerl的使用

    iOS提供了使用其他app预览文件的支持,这就是Document Interaction Controller.此外,iOS也支持文件关联,允许其他程序调用你的app打开某种文件.而且,从4.2开始, ...

  10. VB.NET 注册表基本操作

    ''' <summary> ''' 注册表设置值 ''' </summary> ''' <param name="strKey"></pa ...