【xml】DOM4J 使用方法(轉載)




DOM4J是一個開源的,基於Java的庫來解析XML文檔,它具有高度的靈活性,高性能和內存效率的API。這是java的優化,使用Java集合像列表和數組。它可以使用DOM,SAX,XPath和XSLT。它解析大型XML文檔時具有極低的內存占用。
Read more >>

Read more >> 環境設置

Read more >>
為了使用DOM4J解析器,應該 dom4j-1.6.1.jar 和 jaxen.jar 在應用程序的類路徑中。下載 dom4j-1.6.1.zip.

什麼情況下使用?

應該考慮使用DOM4J解析器的時候:
  • 需要知道很多關於文檔的結構
  • 需要將文檔的部分圍繞(例如,可能需要某些元素進行排序)
  • 需要使用的文件中的信息超過一次
  • 你是一個Java開發人員,並希望利用XML的Java的優化解析。

會得到什麼?

當解析一個DOM4J解析XML文檔,可以靈活地得到一個樹形結構,其中包含所有文檔的元素,而不會影響應用程序的內存占用。DOM4J提供了多種可用於檢查的情況下文檔內容和結構的實用功能是良好的結構,其結構是公知的。 DOM4J使用XPath表達式來瀏覽XML文檔。

優勢

DOM4J使Java開發的靈活性和XML解析代碼易於維護。它是輕量級的,快速的API。

DOM4J 類

DOM4J定義了幾個Java類。以下是最常見的類:
  • Document - 表示整個XML文檔。文檔Document對象是通常被稱為DOM樹。
  • Element - 表示一個XML元素。 Element對象有方法來操作其子元素,它的文本,屬性和名稱空間。
  • Attribute - 表示元素的屬性。屬性有方法來獲取和設置屬性的值。它有父節點和屬性類型。
  • Node - 代表元素,屬性或處理指令

常見DOM4J的方法

當使用DOM4J,還有經常用到的幾種方法:
  • SAXReader.read(xmlSource)() - 構建XML源的DOM4J文檔。
  • Document.getRootElement() - 得到的XML的根元素。
  • Element.node(index) - 獲得在元素特定索引XML節點。
  • Element.attributes() - 獲取一個元素的所有屬性。
  • Node.valueOf(@Name) - 得到元件的給定名稱的屬性的值。

From: DOM4J使用步驟 ,

【xml】DOM 使用方法(轉載)

使用DOM的步驟

以下是在使用DOM解析器解析文檔使用的步驟。
Read more >>
    Read more >>
  • 導入XML相關的軟件包。
  • 創建DocumentBuilder
  • 從文件或流創建一個文檔
  • 提取根元素
  • 檢查屬性
  • 檢查子元素
Read more >>
導入XML相關的軟件包
import org.w3c.dom.*;
import javax.xml.parsers.*;
import java.io.*;
創建 DocumentBuilder
DocumentBuilderFactory factory =
DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
從文件或流創建一個文檔
StringBuilder xmlStringBuilder = new StringBuilder();
xmlStringBuilder.append("<?xml version="1.0"?> <class> </class>");
ByteArrayInputStream input =  new ByteArrayInputStream(
   xmlStringBuilder.toString().getBytes("UTF-8"));
Document doc = builder.parse(input);
提取根元素
Element root = document.getDocumentElement();
檢查屬性
//returns specific attribute
getAttribute("attributeName"); 
//returns a Map (table) of names/values
getAttributes(); 
檢查子元素
//returns a list of subelements of specified name
getElementsByTagName("subelementName"); 
//returns a list of all child nodes
getChildNodes(); 

演示示例

這是輸入需要解析的 xml 文件:
<?xml version="1.0"?>
<class>
   <student rollno="393">
      <firstname>dinkar</firstname>
      <lastname>kad</lastname>
      <nickname>dinkar</nickname>
      <marks>85</marks>
   </student>
   <student rollno="493">
      <firstname>Vaneet</firstname>
      <lastname>Gupta</lastname>
      <nickname>vinni</nickname>
      <marks>95</marks>
   </student>
   <student rollno="593">
      <firstname>jasvir</firstname>
      <lastname>singn</lastname>
      <nickname>jazz</nickname>
      <marks>90</marks>
   </student>
</class>

演示示例:
DomParserDemo.java
package com.yiibai.xml;

import java.io.File;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.DocumentBuilder;
import org.w3c.dom.Document;
import org.w3c.dom.NodeList;
import org.w3c.dom.Node;
import org.w3c.dom.Element;

public class DomParserDemo {
   public static void main(String[] args){

      try { 
         File inputFile = new File("input.txt");
         DocumentBuilderFactory dbFactory 
            = DocumentBuilderFactory.newInstance();
         DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
         Document doc = dBuilder.parse(inputFile);
         doc.getDocumentElement().normalize();
         System.out.println("Root element :" 
            + doc.getDocumentElement().getNodeName());
         NodeList nList = doc.getElementsByTagName("student");
         System.out.println("----------------------------");
         for (int temp = 0; temp < nList.getLength(); temp++) {
            Node nNode = nList.item(temp);
            System.out.println("\nCurrent Element :" 
               + nNode.getNodeName());
            if (nNode.getNodeType() == Node.ELEMENT_NODE) {
               Element eElement = (Element) nNode;
               System.out.println("Student roll no : " 
                  + eElement.getAttribute("rollno"));
               System.out.println("First Name : " 
                  + eElement
                  .getElementsByTagName("firstname")
                  .item(0)
                  .getTextContent());
               System.out.println("Last Name : " 
               + eElement
                  .getElementsByTagName("lastname")
                  .item(0)
                  .getTextContent());
               System.out.println("Nick Name : " 
               + eElement
                  .getElementsByTagName("nickname")
                  .item(0)
                  .getTextContent());
               System.out.println("Marks : " 
               + eElement
                  .getElementsByTagName("marks")
                  .item(0)
                  .getTextContent());
            }
         }
      } catch (Exception e) {
         e.printStackTrace();
      }
   }
}
這將產生以下結果:
Root element :class
----------------------------

Current Element :student
Student roll no : 393
First Name : dinkar
Last Name : kad
Nick Name : dinkar
Marks : 85

Current Element :student
Student roll no : 493
First Name : Vaneet
Last Name : Gupta
Nick Name : vinni
Marks : 95

Current Element :student
Student roll no : 593
First Name : jasvir
Last Name : singn
Nick Name : jazz
Marks : 90




From: DOM解析器介紹 , DOM使用步驟

【xml】 SAX使用方法 (轉載)



SAX official website     SAX API 下載連結

在Sax的解析過程中,讀取到文檔開頭、結尾,元素的開頭和結尾都會觸發一些回調方法,你可以在這些回調方法中進行相應事件處理
Read more >>
這四個方法是:startDocument() 、 endDocument()、 startElement()、 endElement。此外,讀取到節點處是不夠的,我們還需要characters()方法來仔細處理元素內包含的內容,將這些回調方法集合起來,便形成了一個類,這個類也就是我們需要的觸發器。

一般從Main方法中讀取文檔,卻在觸發器中處理文檔,這就是所謂的事件驅動解析方法。


Read more >>
如上圖,在觸發器中,首先開始讀取文檔,然後開始逐個解析元素,每個元素中的內容會返回到characters()方法,接著結束元素讀取,所有元素讀取完後,結束文檔解析。



現在我們開始創建觸發器這個類,要創建這個類首先需要繼承DefaultHandler

創建SaxHandler,並覆寫相應方法:
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
public class SaxHandler extends DefaultHandler {
    /* 此方法有三个参数
       arg0是传回来的字符数组,其包含元素内容
       arg1和arg2分别是数组的开始位置和结束位置 */
    @Override
    public void characters(char[] arg0, int arg1, int arg2) throws SAXException {
        String content = new String(arg0, arg1, arg2);
        System.out.println(content);
        super.characters(arg0, arg1, arg2);
    }
    @Override
    public void endDocument() throws SAXException {
        System.out.println("\n…………结束解析文档…………");
        super.endDocument();
    }
    /* arg0是名称空间
       arg1是包含名称空间的标签,如果没有名称空间,则为空
       arg2是不包含名称空间的标签 */
    @Override
    public void endElement(String arg0, String arg1, String arg2)
            throws SAXException {
        System.out.println("结束解析元素  " + arg2);
        super.endElement(arg0, arg1, arg2);
    }
    @Override
    public void startDocument() throws SAXException {
        System.out.println("…………开始解析文档…………\n");
        super.startDocument();
    }
    /*arg0是名称空间
      arg1是包含名称空间的标签,如果没有名称空间,则为空
      arg2是不包含名称空间的标签
      arg3很明显是属性的集合 */
    @Override
    public void startElement(String arg0, String arg1, String arg2,
            Attributes arg3) throws SAXException {
        System.out.println("开始解析元素 " + arg2);
        if (arg3 != null) {
            for (int i = 0; i < arg3.getLength(); i++) {
                 // getQName()是获取属性名称,
                System.out.print(arg3.getQName(i) + "=\"" + arg3.getValue(i) + "\"");
            }
        }
        System.out.print(arg2 + ":");
        super.startElement(arg0, arg1, arg2, arg3);
    }
}

XML文档:
<?xml version="1.0" encoding="UTF-8"?>
<books>
   <book id="001">
      <title>Harry Potter</title>
      <author>J K. Rowling</author>
   </book>
   <book id="002">
      <title>Learning XML</title>
      <author>Erik T. Ray</author>
   </book>
</books>
 TestDemo测试类:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import java.io.File;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
public class TestDemo {
    public static void main(String[] args) throws Exception {
        // 1.实例化SAXParserFactory对象
        SAXParserFactory factory = SAXParserFactory.newInstance();
        // 2.创建解析器
        SAXParser parser = factory.newSAXParser();
        // 3.获取需要解析的文档,生成解析器,最后解析文档
        File f = new File("books.xml");
        SaxHandler dh = new SaxHandler();
        parser.parse(f, dh);
    }
}
 输出结果:

上面的虽然正确显示了执行流程,但是输出却很乱
为了更加清晰的执行此流程,我们还可以重写SaxHandler,使其将原先的xml文档还原一遍
重写的SaxHandler类:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
public class SaxHandler extends DefaultHandler {
    @Override
    public void characters(char[] arg0, int arg1, int arg2) throws SAXException {
        System.out.print(new String(arg0, arg1, arg2));
        super.characters(arg0, arg1, arg2);
    }
    @Override
    public void endDocument() throws SAXException {
        System.out.println("\n结束解析");
        super.endDocument();
    }
    @Override
    public void endElement(String arg0, String arg1, String arg2)
            throws SAXException {
        System.out.print("</");
        System.out.print(arg2);
        System.out.print(">");
        super.endElement(arg0, arg1, arg2);
    }
    @Override
    public void startDocument() throws SAXException {
        System.out.println("开始解析");
        String s = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>";
        System.out.println(s);
        super.startDocument();
    }
    @Override
    public void startElement(String arg0, String arg1, String arg2,
            Attributes arg3) throws SAXException {
         
        System.out.print("<");
        System.out.print(arg2);
         
        if (arg3 != null) {
            for (int i = 0; i < arg3.getLength(); i++) {
                System.out.print(" " + arg3.getQName(i) + "=\"" + arg3.getValue(i) + "\"");
            }
        }
        System.out.print(">");
        super.startElement(arg0, arg1, arg2, arg3);
    }
}
 执行结果:











From: 使用SAX解析 ,  清新下午茶 , developerWorkers