XML解析-最快的方式SAX

weixin_34208283發表於2018-05-02

XML是一種通用的資料交換格式,它的平臺無關性、語言無關性、系統無關性、給資料整合與互動帶來了極大的方便。XML在不同的語言環境中解析方式都是一樣的,只不過實現的語法不同而已。

XML 的解析方式分為四種:1、 DOM 解析;2、 SAX 解析;3、 JDOM 解析;4、 DOM4J 解析。其中前兩種屬於基礎方法,是官方提供的平臺無關的解析方式;後兩種屬於擴充套件方法,它們是在基礎的方法上擴充套件出來的,只適用於java平臺。

下面主要介紹最快的解析方式SAX解析:
SAX的全稱是Simple APIs for XML,也即XML簡單應用程式介面。與DOM不同,SAX提供的訪問模式是一種順序模式,這是一種快速讀寫XML資料的方式。當使用SAX分析器對XML文件進行分析時,會觸發一系列事件,並啟用相應的事件處理函式,應用程式通過這些事件處理函式實現對XML文件的訪問,因而SAX介面也被稱作事件驅動介面。

優點:

1、採用事件驅動模式,對記憶體耗費比較小。

2、適用於只處理XML檔案中的資料時。

缺點:

1、編碼比較麻煩。

2、很難同時訪問XML檔案中的多處不同資料。
Book為實體類;SAXTest為解析類;
如下:
public class Book {

private String id;
private String name;
private String author;
private String year;
private String price;
private String language;
public String getId() {
    return id;
}
public void setId(String id) {
    this.id = id;
}
public String getName() {
    return name;
}
public void setName(String name) {
    this.name = name;
}
public String getAuthor() {
    return author;
}
public void setAuthor(String author) {
    this.author = author;
}
public String getYear() {
    return year;
}
public void setYear(String year) {
    this.year = year;
}
public String getPrice() {
    return price;
}
public void setPrice(String price) {
    this.price = price;
}
public String getLanguage() {
    return language;
}
public void setLanguage(String language) {
    this.language = language;
}

}


public class SAXTest {
/**
* @param args
*/
public static void main(String[] args) {
SAXParserFactory factory = SAXParserFactory.newInstance();
try {
SAXParser parser = factory.newSAXParser();
SAXParserHandler handler = new SAXParserHandler();
parser.parse("books.xml", handler);
System.out.println("!~!共有" + handler.getBookList().size()
+ "本書");
for (Book book : handler.getBookList()) {
System.out.println(book.getId());
System.out.println(book.getName());
System.out.println(book.getAuthor());
System.out.println(book.getYear());
System.out.println(book.getPrice());
System.out.println(book.getLanguage());
System.out.println("----finish----");
}
} catch (ParserConfigurationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SAXException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}

public class SAXParserHandler extends DefaultHandler {
String value = null;
Book book = null;
private ArrayList<Book> bookList = new ArrayList<Book>();
public ArrayList<Book> getBookList() {
return bookList;
}

int bookIndex = 0;
/**
 * 用來標識解析開始
 */
@Override
public void startDocument() throws SAXException {
    // TODO Auto-generated method stub
    super.startDocument();
    System.out.println("SAX解析開始");
}

/**
 * 用來標識解析結束
 */
@Override
public void endDocument() throws SAXException {
    // TODO Auto-generated method stub
    super.endDocument();
    System.out.println("SAX解析結束");
}

/**
 * 解析xml元素
 */
@Override
public void startElement(String uri, String localName, String qName,
        Attributes attributes) throws SAXException {
    //呼叫DefaultHandler類的startElement方法
    super.startElement(uri, localName, qName, attributes);
    if (qName.equals("book")) {
        bookIndex++;
        //建立一個book物件
        book = new Book();
        //開始解析book元素的屬性
        System.out.println("======================開始遍歷某一本書的內容=================");
        //不知道book元素下屬性的名稱以及個數,如何獲取屬性名以及屬性值
        int num = attributes.getLength();
        for(int i = 0; i < num; i++){
            System.out.print("book元素的第" + (i + 1) +  "個屬性名是:"
                    + attributes.getQName(i));
            System.out.println("---屬性值是:" + attributes.getValue(i));
            if (attributes.getQName(i).equals("id")) {
                book.setId(attributes.getValue(i));
            }
        }
    }
    else if (!qName.equals("name") && !qName.equals("bookstore")) {
        System.out.print("節點名是:" + qName + "---");
    }
}

@Override
public void endElement(String uri, String localName, String qName)
        throws SAXException {
    //呼叫DefaultHandler類的endElement方法
    super.endElement(uri, localName, qName);
    //判斷是否針對一本書已經遍歷結束
    if (qName.equals("book")) {
        bookList.add(book);
        book = null;
        System.out.println("======================結束遍歷某一本書的內容=================");
    }
    else if (qName.equals("name")) {
        book.setName(value);
    }
    else if (qName.equals("author")) {
        book.setAuthor(value);
    }
    else if (qName.equals("year")) {
        book.setYear(value);
    }
    else if (qName.equals("price")) {
        book.setPrice(value);
    }
    else if (qName.equals("language")) {
        book.setLanguage(value);
    }
}

@Override
public void characters(char[] ch, int start, int length)
        throws SAXException {
    // TODO Auto-generated method stub
    super.characters(ch, start, length);
    value = new String(ch, start, length);
    if (!value.trim().equals("")) {
        System.out.println("節點值是:" + value);
    }
}

}


解析xml入庫:
package xmlParse;

import java.io.File;
import java.sql.*;
import java.util.Iterator;
import java.util.List;

import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;

import org.xml.sax.helpers.DefaultHandler;

import java.io.IOException;

public class JieXiXml extends DefaultHandler{

public static void main(String[] args) throws IOException{  
  
    System.out.println("提取xml資料並匯入資料庫");
    String path = "C:/Users/admin/Desktop/";
    //讀取xml檔案的資料並寫入資料庫中
     //InsertData(path);
     BianliXML(path);
    //讀取資料庫中的資料並寫入xml文件
     // SelectData();
    
     
      }  



@SuppressWarnings("null")
private static void InsertData(String path) {

    Connection conn = null;// 建立一個資料庫連線  
    PreparedStatement pstmt = null;// 建立預編譯語句物件,一般都是用這個而不用Statement  
    StringBuffer sql = new StringBuffer("insert into sensor_all_data(sensor_imei,sensor_des,sensor_length,sensor_success_or_fail,sensor_first_time,sensor_accept_time) values ");  
    //path = "C:/Users/admin/Desktop/";
   
    try{  
        JdbcUtil ju = new JdbcUtil();
        conn = ju.getGJZXCon();
        conn.setAutoCommit(false);
        //準備執行sql語句
                
        //讀取xml檔案  
        
       // Document doc=new SAXReader().read(new InputStreamReader(
            //  new FileInputStream(new File(path)),"utf-8"));  
       // Element node = doc.getRootElement();  
        //System.out.println("匯入資料庫的xml資料如下:\n"+ System.currentTimeMillis());
        
       // pstmt=conn.prepareStatement(sql); 
      //選擇xml檔案的節點  

        File file = new File(path);
        SAXParserFactory saxParFac = SAXParserFactory.newInstance();
        SaxParseXml parseXml = new SaxParseXml();
       
        SAXParser saxParser = saxParFac.newSAXParser();
        saxParser.parse(file, parseXml);
        long s = System.currentTimeMillis();
        List<XmlObj> itemList=parseXml.getContactList(); 
        
      //遍歷讀出的xml中的節點  
       int i=0;
       int size = itemList.size();
       for(Iterator<XmlObj> iter=itemList.iterator();iter.hasNext();){  
           XmlObj xo = iter.next();
           String s1 = xo.getImei();
           String s2 = xo.getDes();
           String s3 = xo.getLen();
           String s4 = xo.getSorf();
           String s5 = xo.getFirsttime();
           String s6 = xo.getAccepttime();
          sql.append("('").append(s1).append("','");
          sql.append(s2).append("','");
          sql.append(s3).append("','");
          sql.append(s4).append("','");
          sql.append(s5).append("','");
          sql.append(s6).append("')");
          i++;
          if(i<size){
             sql.append(",");
          }
           //System.out.println(sensor_imei + "\t" + sensor_des + "\t" + sensor_length + "\t" + 
            //     sensor_success_or_fail + "\t" + sensor_first_time + "\t" + sensor_accept_time + "\t" + "\t" );
           //為sql語句賦值  
         /*  pstmt.setString(1, sensor_imei);  
           pstmt.setString(2, sensor_des);  
           pstmt.setString(3, sensor_length);  
           pstmt.setString(4, sensor_success_or_fail);  
           pstmt.setString(5, sensor_first_time);  
           pstmt.setString(6, sensor_accept_time);   */
           //pstmt.addBatch(); 
       }  
       long end = System.currentTimeMillis();;
       System.out.println("迴圈時間:\n"+ (System.currentTimeMillis()-s)/1000+"秒");
       pstmt=conn.prepareStatement(sql.toString()); 
       pstmt.executeUpdate();  
       conn.commit();
       conn.close();
       pstmt.close();
       System.out.print("將XML文件資料匯入資料庫成功\n"+ (System.currentTimeMillis()-end)/1000+"秒");  
   }
   //捕獲連線資料庫異常  
   catch ( SQLException sqlex ) {  
       System.err.println( "無法連線資料庫" );  
       sqlex.printStackTrace();   
   }  
   catch(Exception e){  
       e.printStackTrace();  
   }finally{  
       try {  
           // 逐一將上面的幾個物件關閉,因為不關閉的話會影響效能、並且佔用資源  
           // 注意關閉的順序,最後使用的最先關閉   
           if (pstmt != null)  
               pstmt.close();  
           if (conn != null)  
               conn.close();   
       } catch (Exception e) {  
           e.printStackTrace();  
       }  
   }  

}

public static void BianliXML(String path){
    // String path = "C:/Users/admin/Desktop/";
        

        File file = new File(path);
        String[] filename = file.list();
        for (String obj : filename) {
            if(obj.endsWith("xml")){
                try {
                    InsertData(path + obj);
                } catch (Exception e) {
                    System.out.println("出現異常");
                }
                // 將已讀檔案刪除
                File fileBak = new File(path + obj);
                fileBak.delete();
            }else{
                continue;
            }
        }
}

}


package xmlParse;

import java.util.ArrayList;
import java.util.List;

import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;

public class SaxParseXml extends DefaultHandler{
//定義一個集合,用於儲存聯絡人物件
private List<XmlObj> conList= new ArrayList<XmlObj>();
private XmlObj xmlobj;
/*
* 定義一個變數用於記錄標籤的名字
* 以便關聯標籤與標籤的文字內容
*/
private String Tag;
@Override
public void startElement(String uri, String localName,
String qName, Attributes attributes) throws SAXException {
Tag=qName;
if("data".equals(qName)){
xmlobj = new XmlObj();
String idValue=attributes.getValue("id");
//xmlobj.setId(idValue);
}
}

@Override
public void endElement(String uri, 
        String localName, String qName) throws SAXException {
    //結束時 ,將標記置為空,防止給Contact內的值重複賦值。
    Tag=null;
    //當讀到contact結束標籤時,說明一個聯絡人讀完了,存到集合中
    if("data".equals(qName)){
        conList.add(xmlobj);
    }
}

@Override
public void characters(char[] ch, int start, int length) 
        throws SAXException {
    //獲取文字內容
    String content=new String(ch,start,length);
    if("imei".equals(Tag)){
        xmlobj.setImei(content);
    }else if("des".equals(Tag)){
        xmlobj.setDes(content);
    }else if("len".equals(Tag)){
        xmlobj.setLen(content);
    }else if("sorf".equals(Tag)){
        xmlobj.setSorf(content);
    }else if("firsttime".equals(Tag)){
        xmlobj.setFirsttime(content);
    }else if("accepttime".equals(Tag)){
        xmlobj.setAccepttime(content);
    }

}
public  List<XmlObj> getContactList(){
    return conList;
}

}

相關文章