天天看點

jaxp解析器用dom方式操作xml文檔的總結

我的個人部落格站點:http://blog.itcodai.com

1. xml解析技術概述

 

   解析xml文檔一般有兩種技術:dom(Document Object Model)和sax(Simple API for XML)。dom即文檔對象模型,是W3C組織推薦的處理xml的一種方式;sax不是官方标準,但它是xml社群事實上的标準,幾乎所有的xml解析器都支援它。

1.1 dom方式

  dom方式會把文本解析成Document對象,把所有元素和文本也解析成一個對象:解析器将标簽解析為Element對象,對内容解析為Text對象,對屬性解析為Attribute。對所有的節點都可以用Node對象表示,當沒有合适的方法調用的時候,才把Node強制轉換成上面的具體類型,上面的類都是Node的子類。

  使用dom方式對xml文檔解析隻需要得到document對象,就可以得到所有節點,因為在記憶體中會解析成樹結構圖。

  • 優點:實作CURD特别友善,操作速度也比較快。
  • 缺點:如果檔案比較大,對記憶體消耗就特别大,極易導緻記憶體溢出,是以dom方式不是和操作大的xml文檔。

1.2 sax方式

  sax方式不是先将文本解析成整個對象,它是讀取一行解析一行。

  • 優點:解析速度快,對記憶體占用少,查找資料特别友善。
  • 缺點:隻适合查找資料,不适合CURD操作。

  針對這兩種方式,有很多解析開發包,主要有jaxp和dom4j,這篇文章先介紹一下jaxp解析器如何用dom方式解析xml文檔。

2. jaxp解析器用dom方式解析xml文檔

 

   jaxp開發包是j2se的一部分,它由

javax.xml

org.w3c.dom

org.xml.sax

包及其子包組成。在

javax.xml.parsers

包中,定義了幾個工廠類,程式員調用這些工廠類,可以得到對xml文檔進行解析的dom和sax的解析器對象。

javax.xml.parsers

包中的DocumentBuilderFactory用于建立dom模式的解析器對象,DocumentBuilderFactory是一個抽象工廠類,它不能直接執行個體化,但是該類提供了一個靜态的

newInstance()

方法,這個方法會根據本地平台預設安裝的解析器,自動建立一個工廠的對象并傳回。

  首先給出個book.xml文檔,如下:

<?xml version="1.0" encoding="UTF-8"?>
<bookstore> 
  <book name="book1" password="123"> 
    <price>59元</price>  
    <name>java神書1^^</name>  
    <author>倪升武</author>  
  </book> 
  <book name="book2" password="123456"> 
    <price>69元</price>  
    <name>java神書2^^</name>  
    <author>倪升武</author>  
  </book> 
</bookstore>
           

  下面我們來使用jaxp具體解析這個book.xml文檔:

2.1 得到節點的值

@Test
public void read() throws Exception{
    DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();//擷取工廠
    DocumentBuilder builder = factory.newDocumentBuilder();//産生解析器
    Document document = builder.parse(new File("src/book.xml"));//解析xml文檔,得到代表文檔的document

    NodeList list = document.getElementsByTagName("price");//傳回所有price節點的集合
    Node price = list.item(); //拿到第一個price節點
    String value = price.getTextContent();//擷取節點的值
    System.out.println(value); //59元    
}
           

2.2 修改節點的值

@Test
public void update() throws Exception{
    DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
    DocumentBuilder builder = factory.newDocumentBuilder();
    Document document = builder.parse(new File("src/book.xml"));

    Node price = document.getElementsByTagName("售價").item();
    price.setTextContent("89元");
    /*javax.xml.tranform包中的Transformer類用于把代表XML檔案的Document對象轉換為某種格式後進行輸出。
     *例如把XML檔案應用樣式表後轉成一個HTML文檔,利用這個對象,當然也可以把Document對象重新寫入到一個XML檔案中。
     *Transformer類通過transform(Source xmlSource, Result outputTarget)方法完成轉換操作,該方法接受一個源和一個目的地。我們可以通過:
     *      javax.xml.transform.dom.DOMSource類來關聯要轉換的document對象,
     *      用javax.xml.transform.stream.StreamResult對象來表示資料的目的地。
     *Transformer抽象類,但是其對象通過TransformerFactory.newTransformer獲得。
     *
    */

    //得到轉換器工廠
    TransformerFactory tf = TransformerFactory.newInstance();
    //得到轉換器
    Transformer ts = tf.newTransformer();   
    ts.transform(new DOMSource(document), new StreamResult(new File("src/book.xml"))); //将修改後的document對象(dom)轉換到book.xml
}
           

2.3 添加新的節點

@Test
public void addNode() throws Exception{
    DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
    DocumentBuilder builder = factory.newDocumentBuilder();
    Document document = builder.parse(new File("src/book.xml"));

    //建立需要增加的節點
    Node price = document.createElement("price");
    price.setTextContent("109元");

    //得到需要增加的節點的父節點
    Node parent = document.getElementsByTagName("book").item();//第一個book節點

    //把需要增加的節點挂到父節點上
    parent.appendChild(price);

    TransformerFactory tf = TransformerFactory.newInstance();
    Transformer ts = tf.newTransformer();
    ts.transform(new DOMSource(document), new StreamResult(new File("src/book.xml")));
}
           

2.4 向指定位置添加新的節點

@Test
public void addNodeWithIndex() throws Exception {
    DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
    DocumentBuilder builder = factory.newDocumentBuilder();
    Document document = builder.parse(new File("src/book.xml"));

    Node node = document.createElement("price");
    node.setTextContent("39元");
    Node parent = document.getElementsByTagName("book").item();
    parent.insertBefore(node, document.getElementsByTagName("name").item());//在書名前添加node

    TransformerFactory tf = TransformerFactory.newInstance();
    Transformer ts = tf.newTransformer();
    ts.transform(new DOMSource(document), new StreamResult(new File("src/book.xml")));
}
           

2.5 删除指定的節點

@Test
public void delete() throws Exception{
    DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
    DocumentBuilder builder = factory.newDocumentBuilder();
    Document document = builder.parse(new File("src/book.xml"));

    NodeList nodes = document.getElementsByTagName("price");//擷取所有售價節點
    for(int i = ; i <= nodes.getLength(); i++){
        if(nodes.item(i).getTextContent().equals("109元")){
            //自己不能删自己,要讓它的父節點來删
            nodes.item(i).getParentNode().removeChild(nodes.item(i));//删除所有售價為109元的節點
        }
    }

    TransformerFactory tf = TransformerFactory.newInstance();
    Transformer ts = tf.newTransformer();
    ts.transform(new DOMSource(document), new StreamResult(new File("src/book.xml")));
}
           

2.6 操作文檔的屬性

@Test
public void updateAttribute() throws Exception{
    DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
    DocumentBuilder builder = factory.newDocumentBuilder();
    Document document = builder.parse(new File("src/book.xml"));

    //操作XML文檔元素時,一般都把元素當做Node對待,但是如果Node沒有合适的方法時,就得轉換成相應的類型
    Node node = document.getElementsByTagName("book").item();
    Element book = null;
    if(node.getNodeType() == Node.ELEMENT_NODE)//在轉換之前,最好先判斷下類型
        book = (Element)node;
    book.setAttribute("name", "--book--");
    book.setAttribute("password", "--123--");

    TransformerFactory tf = TransformerFactory.newInstance();
    Transformer ts = tf.newTransformer();
    ts.transform(new DOMSource(document), new StreamResult(new File("src/book.xml")));
}
           

  以上就是jaxp解析器使用dom方式對xml文檔進行解析的總結,可以看出,如果隻讀不寫,隻要擷取解析器工廠–>擷取解析器–>将xml轉換成document,然後開始擷取想要擷取的資料。如果要向xml文檔中寫資料,那麼要擷取轉換器工廠–>擷取轉換器–>将document轉換成xml。是以很明顯,這是兩個相反的過程。

—–樂于分享,共同進步!

—–更多文章請看:http://blog.csdn.net/eson_15