zoukankan      html  css  js  c++  java
  • 【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

    读取的时候应当注意的事项是调用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操作。

  • 相关阅读:
    redis特性,使用场景
    docker 界面话管理工具Portainer
    解决streamsets jdbc全量模式数据重复问题
    clickhouse 行列转换
    clickHouse 常用命令
    mysqldump导出数据
    oracle 迁移到clickhouse 45亿条数据
    clickHouse 导入/删除/更新数据
    clickhouse Mysql 数据类型对比
    maven 的使用
  • 原文地址:https://www.cnblogs.com/kuangdaoyizhimei/p/4357629.html
Copyright © 2011-2022 走看看