【JAVA解析XML文件实现CRUD操作】

一、简介。

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文档的一个节点。

 1 package p00.domain;

 2 

 3 public class Book {

 4     public String title;

 5     public double price;

 6     public String id;

 7     public String getId()

 8     {

 9     return id;

10     }

11     public void setId(String id)

12     {

13     this.id=id;

14     }

15     public String getTitle()

16     {

17     return title;

18     }

19     public double getPrice()

20     {

21     return price;

22     }

23     public void setTitle(String title)

24     {

25     this.title=title;

26     }

27     public void setPrice(double price)

28     {

29     this.price=price;

30     }

31     public String toString()

32     {

33     return "图书ISBN为:"+id+"   书名为:"+title+"    价格为:"+price;

34     }

35     

36 }
Book.java

得到Document对象的公共方法:

 1 private static Document getDocument() throws Exception {

 2     DocumentBuilderFactory dbf=DocumentBuilderFactory.newInstance();

 3     //获得解析器实例

 4     DocumentBuilder db=dbf.newDocumentBuilder();

 5     //获得Document实例

 6     File file=new File("xmldata/books.xml");

 7     if(!file.exists())

 8     {

 9         System.out.println("目标文件不存在!");

10         return null;

11     }

12     Document document=db.parse(file);

13     return document;

14     }
View Code

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

 1  /**

 2     * 根据得到的Document对象将其中的内容保存到硬盘中的XML文件,完成持久化的工作。

 3     * @param document

 4     * @throws Exception

 5     */

 6     private static void saveToAnotherPlace(Document document) throws Exception {

 7     TransformerFactory tf=TransformerFactory.newInstance();

 8     Transformer transformer=tf.newTransformer();

 9     

10     Element rootSource=document.getDocumentElement();

11     Source xmlSource=new DOMSource(rootSource);

12     Result outputTarget=new StreamResult("xmldata/books1.xml");

13     transformer.transform(xmlSource, outputTarget);

14     }
View Code

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

 1 <?xml version="1.0" encoding="UTF-8"?>

 2 <books>

 3     <book id="book1">

 4         <title>JAVA编程思想</title>

 5         <price>80.00</price>

 6     </book>

 7     <book id="book2">

 8         <title>JAVA核心技术</title>

 9         <price>100.00</price>

10     </book>

11 </books>

1、读取(R)

  1 package p01.getElementsByDomDemo;

  2 

  3 import java.io.File;

  4 import java.util.ArrayList;

  5 import java.util.Iterator;

  6 import java.util.List;

  7 

  8 import javax.xml.parsers.DocumentBuilder;

  9 import javax.xml.parsers.DocumentBuilderFactory;

 10 

 11 import org.w3c.dom.Document;

 12 import org.w3c.dom.Element;

 13 import org.w3c.dom.Node;

 14 import org.w3c.dom.NodeList;

 15 

 16 import p00.domain.Book;

 17 

 18 public class getElementsDemo {

 19     /**

 20      * 该类演示使用dom对xml文档的查询,包括元素节点查询和元素属性值查询。

 21      */

 22     public static List<Book>list=new ArrayList<Book>();

 23     public static void main(String[] args) throws Exception {

 24     /**

 25      * 得到所有的元素并保存到list中。

 26      */

 27         list=getAllElementsToList();

 28         traverse(list);//遍历集合,查看集合中的内容是否正确。

 29     }

 30     /**

 31      * 该方法用于遍历集合元素。

 32      * @param list2

 33      */

 34     private static void traverse(List<Book> list2) {

 35     System.out.println();

 36     System.out.println("得到的集合内容为:");

 37     Iterator<Book>it=list2.iterator();

 38     while(it.hasNext())

 39     {

 40         Book book=it.next();

 41         System.out.println(book);

 42     }

 43     }

 44     public static List<Book> getAllElementsToList() throws Exception

 45     {

 46     List<Book>list=new ArrayList<Book>();

 47     DocumentBuilderFactory dbf=DocumentBuilderFactory.newInstance();

 48     DocumentBuilder db=dbf.newDocumentBuilder();

 49     File file=new File("xmldata/books.xml");

 50     if(!file.exists())

 51     {

 52         System.out.println("目标文件不存在!");

 53         return list;

 54     }

 55     Document domtree=db.parse(file);

 56     //得到根元素列表

 57     NodeList roots=domtree.getElementsByTagName("books");

 58     Node root=roots.item(0);

 59     //根据根节点,遍历xml文档中的元素。

 60     NodeList books=root.getChildNodes();

 61     //显示结果为5本书,事实上包含了回车和换行。

 62 //    System.out.println("books节点的子节点长度为:"+books.getLength());

 63     //遍历得到的结果集,并去除回车和换行。

 64     for(int i=0;i<books.getLength();i++)

 65     {

 66         Node node=books.item(i);

 67         String name=node.getNodeName();

 68         if("book".equals(name))

 69         {

 70         Book book=new Book();

 71         Element bookElement=(Element)node;//父接口向子接口强制转换发生异常。

 72         String idValue=bookElement.getAttribute("id");

 73         book.setId(idValue);

 74         System.out.println("id属性值为:"+idValue);

 75         

 76         NodeList tp=node.getChildNodes();

 77         //这里由于回车换行的关系,所以长度为5

 78 //        System.out.println("book节点的子节点长度为:"+tp.getLength());

 79         for(int j=0;j<tp.getLength();j++)

 80         {

 81             Node node1=tp.item(j);

 82             String nodename=node1.getNodeName();

 83             if("title".equals(nodename))

 84             {

 85             String bookName=node1.getTextContent();

 86             book.setTitle(bookName);

 87             System.out.println("书名为:"+bookName);

 88             }

 89             if("price".equals(nodename))

 90             {

 91             String bookPrice=node1.getTextContent();

 92             System.out.println("价格为:"+bookPrice);

 93             double bookprice=Double.parseDouble(bookPrice);

 94             book.setPrice(bookprice);

 95             }

 96         }

 97         list.add(book);

 98         }

 99         else

100         continue;

101     }

102     return list;

103     }

104 

105 }
View Code

【JAVA解析XML文件实现CRUD操作】

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

2、修改(U)

 1 /**

 2      * 修改XML文档的内容,将JAVA编程思想修改为Thinking in Java

 3      * @param document

 4      */

 5     private static void updateXMLContent(Document document) {

 6     Element root=document.getDocumentElement();

 7     NodeList books=root.getElementsByTagName("book");

 8     for(int i=0;i<books.getLength();i++)

 9     {

10         Node node=books.item(i);

11         Element book=(Element)node;

12         String id=book.getAttribute("id");

13         if("book1".equals(id))

14         {

15         NodeList childs=node.getChildNodes();

16         for(int j=0;j<childs.getLength();j++)

17         {

18             Node title=childs.item(j);

19             String nodeName=title.getNodeName();

20             if("title".equals(nodeName))

21             {

22             Element aim=(Element)title;

23             aim.setTextContent("Thinking in java");

24             }

25             else

26             continue;

27         }

28         }

29         else

30         continue;

31     }

32     }
View Code

修改后的内容:

 1 <?xml version="1.0" encoding="UTF-8"?><books>

 2     <book id="book1">

 3         <title>Thinking in java</title>

 4         <price>80.00</price>

 5     </book>

 6     <book id="book2">

 7         <title>JAVA核心技术</title>

 8         <price>100.00</price>

 9     </book>

10 </books>

3、删除(D)

 1 /**

 2      * 删除指定元素的方法,要求:删除id值为002的元素。

 3      * @param document

 4      */

 5     private static void removeOldNodeFromXML(Document document) {

 6 

 7     Element root=document.getDocumentElement();

 8     NodeList books=root.getElementsByTagName("book");

 9     for(int i=0;i<books.getLength();i++)

10     {

11         Node node=books.item(i);

12         Element book=(Element)node;

13         String id=book.getAttribute("id");

14         if("book2".equals(id))

15         {

16         Node parent=node.getParentNode();

17         parent.removeChild(node);

18         }

19         else

20         continue;

21     }

22     

23     }
View Code

删除后内容:

1 <?xml version="1.0" encoding="UTF-8"?><books>

2     <book id="book1">

3         <title>JAVA编程思想</title>

4         <price>80.00</price>

5     </book>

6     

7 </books>

4、添加(C)

 1  /**

 2      * 添加新元素的方法。

 3      * :添加一个新节点,节点要求:id为book3,title为计算机网络,price为1.0

 4      * @param document

 5      */

 6     private static void addNewNodeToXML(Document document) {

 7     Element root=document.getDocumentElement();

 8     Element book=document.createElement("book");

 9     book.setAttribute("id", "book3");

10     Element title=document.createElement("title");

11     Element price=document.createElement("price");

12     title.setTextContent("计算机网络");

13     price.setTextContent("1.0");

14     book.appendChild(title);

15     book.appendChild(price);

16     root.appendChild(book);

17     }
View Code

添加后内容:

 1 <?xml version="1.0" encoding="UTF-8"?><books>

 2     <book id="book1">

 3         <title>JAVA编程思想</title>

 4         <price>80.00</price>

 5     </book>

 6     <book id="book2">

 7         <title>JAVA核心技术</title>

 8         <price>100.00</price>

 9     </book>

10 <book id="book3"><title>计算机网络</title><price>1.0</price></book></books>

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

5、完整代码。

  1 package p01.getElementsByDomDemo;

  2 

  3 import java.io.File;

  4 

  5 import javax.xml.parsers.DocumentBuilder;

  6 import javax.xml.parsers.DocumentBuilderFactory;

  7 import javax.xml.transform.Result;

  8 import javax.xml.transform.Source;

  9 import javax.xml.transform.Transformer;

 10 import javax.xml.transform.TransformerFactory;

 11 import javax.xml.transform.dom.DOMSource;

 12 import javax.xml.transform.stream.StreamResult;

 13 

 14 import org.w3c.dom.Document;

 15 import org.w3c.dom.Element;

 16 import org.w3c.dom.Node;

 17 import org.w3c.dom.NodeList;

 18 

 19 public class CUDDemo {

 20 

 21     public static void main(String[] args) throws Exception {

 22     Document document=getDocument();

 23     //修改操作:把id为book1的书籍title的值改为Thinking in java

 24 //    updateXMLContent(document);

 25     

 26     //添加新元素操作

 27 //    addNewNodeToXML(document);

 28     

 29     //删除指定元素的方法。

 30 //    removeOldNodeFromXML(document);

 31     //作为一个独立的方法将得到的document对象中的内容写入到硬盘中的文件。

 32     saveToAnotherPlace(document);

 33     }

 34     /**

 35      * 删除指定元素的方法,要求:删除id值为002的元素。

 36      * @param document

 37      */

 38     private static void removeOldNodeFromXML(Document document) {

 39 

 40     Element root=document.getDocumentElement();

 41     NodeList books=root.getElementsByTagName("book");

 42     for(int i=0;i<books.getLength();i++)

 43     {

 44         Node node=books.item(i);

 45         Element book=(Element)node;

 46         String id=book.getAttribute("id");

 47         if("book2".equals(id))

 48         {

 49         Node parent=node.getParentNode();

 50         parent.removeChild(node);

 51         }

 52         else

 53         continue;

 54     }

 55     

 56     }

 57     /**

 58      * 添加新元素的方法。

 59      * :添加一个新节点,节点要求:id为book3,title为计算机网络,price为1.0

 60      * @param document

 61      */

 62     private static void addNewNodeToXML(Document document) {

 63     Element root=document.getDocumentElement();

 64     Element book=document.createElement("book");

 65     book.setAttribute("id", "book3");

 66     Element title=document.createElement("title");

 67     Element price=document.createElement("price");

 68     title.setTextContent("计算机网络");

 69     price.setTextContent("1.0");

 70     book.appendChild(title);

 71     book.appendChild(price);

 72     root.appendChild(book);

 73     }

 74 

 75     /**

 76      * 修改XML文档的内容,将JAVA编程思想修改为Thinking in Java

 77      * @param document

 78      */

 79     private static void updateXMLContent(Document document) {

 80     Element root=document.getDocumentElement();

 81     NodeList books=root.getElementsByTagName("book");

 82     for(int i=0;i<books.getLength();i++)

 83     {

 84         Node node=books.item(i);

 85         Element book=(Element)node;

 86         String id=book.getAttribute("id");

 87         if("book1".equals(id))

 88         {

 89         NodeList childs=node.getChildNodes();

 90         for(int j=0;j<childs.getLength();j++)

 91         {

 92             Node title=childs.item(j);

 93             String nodeName=title.getNodeName();

 94             if("title".equals(nodeName))

 95             {

 96             Element aim=(Element)title;

 97             aim.setTextContent("Thinking in java");

 98             }

 99             else

100             continue;

101         }

102         }

103         else

104         continue;

105     }

106     }

107 

108    /**

109     * 根据得到的Document对象将其中的内容保存到硬盘中的XML文件,完成持久化的工作。

110     * @param document

111     * @throws Exception

112     */

113     private static void saveToAnotherPlace(Document document) throws Exception {

114     TransformerFactory tf=TransformerFactory.newInstance();

115     Transformer transformer=tf.newTransformer();

116     

117     Element rootSource=document.getDocumentElement();

118     Source xmlSource=new DOMSource(rootSource);

119     Result outputTarget=new StreamResult("xmldata/books1.xml");

120     transformer.transform(xmlSource, outputTarget);

121     }

122 

123     /**

124      * 得到Document对象的方法。

125      * @return

126      * @throws Exception

127      */

128     private static Document getDocument() throws Exception {

129     DocumentBuilderFactory dbf=DocumentBuilderFactory.newInstance();

130     //获得解析器实例

131     DocumentBuilder db=dbf.newDocumentBuilder();

132     //获得Document实例

133     File file=new File("xmldata/books.xml");

134     if(!file.exists())

135     {

136         System.out.println("目标文件不存在!");

137         return null;

138     }

139     Document document=db.parse(file);

140     return document;

141     }

142 

143 }
View Code

三、SAX

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

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

 1 package p02.readElementsBySaxDemo;

 2 

 3 import java.io.File;

 4 

 5 import javax.xml.parsers.ParserConfigurationException;

 6 import javax.xml.parsers.SAXParser;

 7 import javax.xml.parsers.SAXParserFactory;

 8 

 9 import org.xml.sax.Attributes;

10 import org.xml.sax.SAXException;

11 import org.xml.sax.helpers.DefaultHandler;

12 

13 /**

14  * 该类的功能是通过Sax技术实现对xml文档的查找操作。

15  * 使用SAX技术不能实现对XML文档的增删改操作。

16  * @author kdyzm

17  *

18  */

19 public class ReadXMLBySax {

20 

21     public static void main(String[] args) throws Exception, SAXException {

22     SAXParserFactory spf=SAXParserFactory.newInstance();

23     SAXParser sp=spf.newSAXParser();

24     File file=new File("xmldata/books.xml");

25     MyHandler mh=new MyHandler();

26     sp.parse(file, mh);

27     }

28 

29 }

30 

31 /**

32  * 该类重写了默认处理类中的部分方法。

33  * @author kdyzm

34  *

35  */

36 class MyHandler extends DefaultHandler

37 {

38     

39     //文档开始的时候触发该事件

40     @Override

41     public void startDocument() throws SAXException {

42     System.out.println("开始解析文档!");

43     super.startDocument();

44     }

45 

46     //文档结束的时候触发该事件

47     @Override

48     public void endDocument() throws SAXException {

49     System.out.println("解析文档结束!");

50     super.endDocument();

51     }

52 

53     //当开始解析一个元素的时候触发该事件

54     @Override

55     public void startElement(String uri, String localName, String qName,

56         Attributes attributes) throws SAXException {

57     System.out.println("开始解析元素:"+qName+"    属性id的值是:"+attributes.getValue("id"));

58     super.startElement(uri, localName, qName, attributes);

59     }

60 

61     //解析完成一个元素的时候触发该事件

62     @Override

63     public void endElement(String uri, String localName, String qName)

64         throws SAXException {

65     super.endElement(uri, localName, qName);

66     System.out.println("解析元素结束:"+qName);

67     }

68 

69     //遇到字符串的时候触发该事件。

70     @Override

71     public void characters(char[] ch, int start, int length)

72         throws SAXException {

73     System.out.println("解析得到的字符串是:"+new String(ch,start,length));

74     super.characters(ch, start, length);

75     }

76     

77 }
View Code

输出:

开始解析文档!

开始解析元素: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

解析文档结束!
View Code

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

你可能感兴趣的:(解析xml)