国产片侵犯亲女视频播放_亚洲精品二区_在线免费国产视频_欧美精品一区二区三区在线_少妇久久久_在线观看av不卡

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|JAVA教程|ASP教程|

服務器之家 - 編程語言 - JAVA教程 - Java中使用DOM和SAX解析XML文件的方法示例

Java中使用DOM和SAX解析XML文件的方法示例

2020-01-16 16:14圣騎士Wind的博客 JAVA教程

這篇文章主要介紹了Java中使用DOM和SAX解析XML文件的方法示例,通過實例文章中最后也給出了一些對比結論,需要的朋友可以參考下

dom4j介紹
  dom4j的項目地址:http://sourceforge.net/projects/dom4j/?source=directory

  dom4j是一個簡單的開源庫,用于處理XML、 XPath和XSLT,它基于Java平臺,使用Java的集合框架,全面集成了DOM,SAX和JAXP。

 

dom4j的使用
  下載了dom4j項目之后,解壓縮,將其jar包(我的當前版本叫做dom4j-1.6.1.jar)加入class path下面。

  (Properties->Java Build Path -> Add External JARs...)。

  之后就可以使用其提供的API進行編程。

 

程序實例1
  第一個程序,用Java代碼生成xml文檔,代碼如下:

?
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
54
55
56
57
58
59
60
61
62
package com.example.xml.dom4j;
 
import java.io.FileOutputStream;
import java.io.FileWriter;
 
import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.XMLWriter;
 
/**
 * dom4j框架學習 使用dom4j框架創建xml文檔并輸出保存
 *
 */
public class Dom4JTest1
{
 
  public static void main(String[] args) throws Exception
  {
    // 第一種方式:創建文檔,并創建根元素
    // 創建文檔:使用了一個Helper類
    Document document = DocumentHelper.createDocument();
 
    // 創建根節點并添加進文檔
    Element root = DocumentHelper.createElement("student");
    document.setRootElement(root);
 
    // 第二種方式:創建文檔并設置文檔的根元素節點
    Element root2 = DocumentHelper.createElement("student");
    Document document2 = DocumentHelper.createDocument(root2);
 
    // 添加屬性
    root2.addAttribute("name", "zhangsan");
    // 添加子節點:add之后就返回這個元素
    Element helloElement = root2.addElement("hello");
    Element worldElement = root2.addElement("world");
 
    helloElement.setText("hello Text");
    worldElement.setText("world text");
 
    // 輸出
    // 輸出到控制臺
    XMLWriter xmlWriter = new XMLWriter();
    xmlWriter.write(document);
 
    // 輸出到文件
    // 格式
    OutputFormat format = new OutputFormat("  ", true);// 設置縮進為4個空格,并且另起一行為true
    XMLWriter xmlWriter2 = new XMLWriter(
        new FileOutputStream("student.xml"), format);
    xmlWriter2.write(document2);
 
    // 另一種輸出方式,記得要調用flush()方法,否則輸出的文件中顯示空白
    XMLWriter xmlWriter3 = new XMLWriter(new FileWriter("student2.xml"),
        format);
    xmlWriter3.write(document2);
    xmlWriter3.flush();
    // close()方法也可以
 
  }
}

 

  程序Console輸出:

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

  生成的一個xml文檔:

?
1
2
3
4
5
6
<?xml version="1.0" encoding="UTF-8"?>
 
<student name="zhangsan">
  <hello>hello Text</hello>
  <world>world text</world>
</student>

 

程序實例2
  程序實例2,讀入xml文檔并分析,將其內容輸出。

  首先,待分析的文檔如下:

?
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
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
<?xml version="1.0" encoding="UTF-8"?>
 
<students name="zhangsan">
  <hello name="lisi">hello Text1</hello>
  <hello name="lisi2">hello Text2</hello>
  <hello name="lisi3">hello Text3</hello>
  <world name="wangwu">world text1</world>
  <world name="wangwu2">world text2</world>
  <world >world text3</world>
</students>
 
 
package com.example.xml.dom4j;
 
import java.io.File;
import java.util.Iterator;
import java.util.List;
 
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
 
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.DOMReader;
import org.dom4j.io.SAXReader;
 
/**
 * dom4j框架學習: 讀取并解析xml
 *
 *
 */
public class Dom4JTest2
{
  public static void main(String[] args) throws Exception
  {
    SAXReader saxReader = new SAXReader();
 
    Document document = saxReader.read(new File("students.xml"));
 
    // 獲取根元素
    Element root = document.getRootElement();
    System.out.println("Root: " + root.getName());
 
    // 獲取所有子元素
    List<Element> childList = root.elements();
    System.out.println("total child count: " + childList.size());
 
    // 獲取特定名稱的子元素
    List<Element> childList2 = root.elements("hello");
    System.out.println("hello child: " + childList2.size());
 
    // 獲取名字為指定名稱的第一個子元素
    Element firstWorldElement = root.element("world");
    // 輸出其屬性
    System.out.println("first World Attr: "
        + firstWorldElement.attribute(0).getName() + "="
        + firstWorldElement.attributeValue("name"));
 
    System.out.println("迭代輸出-----------------------");
    // 迭代輸出
    for (Iterator iter = root.elementIterator(); iter.hasNext();)
    {
      Element e = (Element) iter.next();
      System.out.println(e.attributeValue("name"));
 
    }
 
    System.out.println("用DOMReader-----------------------");
    DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
    DocumentBuilder db = dbf.newDocumentBuilder();
    // 注意要用完整類名
    org.w3c.dom.Document document2 = db.parse(new File("students.xml "));
 
    DOMReader domReader = new DOMReader();
 
    // 將JAXP的Document轉換為dom4j的Document
    Document document3 = domReader.read(document2);
 
    Element rootElement = document3.getRootElement();
 
    System.out.println("Root: " + rootElement.getName());
 
  }
 
}

 

  代碼運行后輸出:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
Root: students
total child count: 6
hello child: 3
first World Attr: name=wangwu
迭代輸出-----------------------
lisi
lisi2
lisi3
wangwu
wangwu2
null
用DOMReader-----------------------
Root: students

 

 

SAX解析XML
下面是SAX實現實體解析的步驟
//下面使用XMLReader 來解析
(一)第一步:新建一個工廠類SAXParserFactory,代碼如下:
SAXParserFactory factory = SAXParserFactory.newInstance();
(二)第二步:讓工廠類產生一個SAX的解析類SAXParser,代碼如下:
SAXParser parser = factory.newSAXParser();
(三)第三步:從SAXPsrser中得到一個XMLReader實例,代碼如下:
XMLReader reader = parser.getXMLReader();
(四)第四步:把自己寫的handler注冊到XMLReader中,一般最重要的就是ContentHandler,代碼如下:
reader.setContentHandler(this);
(五)第五步:將一個xml文檔或者資源變成一個java可以處理的InputStream流后,解析正式開始,代碼如下:
reader.parse(new InputSource(is));
 
 
//下面使用SAXParser來解析
(一)第一步:新建一個工廠類SAXParserFactory,代碼如下:
SAXParserFactory factory = SAXParserFactory.newInstance();
(二)第二步:讓工廠類產生一個SAX的解析類SAXParser,代碼如下:
SAXParser parser = factory.newSAXParser();
(三)第三步:將一個xml文檔或者資源變成一個java可以處理的InputStream流后,解析正式開始,代碼如下:
parser.parse(is,this);
估計大家都看到了ContentHandler ,下面具體的講下
解析開始之前,需要向XMLReader/SAXParser 注冊一個ContentHandler,也就是相當于一個事件監聽器,在ContentHandler中定義了很多方法
//設置一個可以定位文檔內容事件發生位置的定位器對象
public void setDocumentLocator(Locator locator)
 
//用于處理文檔解析開始事件
public void startDocument()throws SAXException
 
//處理元素開始事件,從參數中可以獲得元素所在名稱空間的uri,元素名稱,屬性類表等信息
public void startElement(String namespacesURI , String localName , String qName , Attributes atts) throws SAXException
 
//處理元素結束事件,從參數中可以獲得元素所在名稱空間的uri,元素名稱等信息
public void endElement(String namespacesURI , String localName , String qName) throws SAXException
 
//處理元素的字符內容,從參數中可以獲得內容
public void characters(char[] ch , int start , int length)  throws SAXException
順便介紹下XMLReader中的方法。
//注冊處理XML文檔解析事件ContentHandler
public void setContentHandler(ContentHandler handler)
 
//開始解析一個XML文檔
public void parse(InputSorce input) throws SAXException

大概的講的差不多了  接下來開始講解解析的步驟
我們還是用上一章的代碼
首先 我們創建一個Person類  用來存儲用戶的信息

?
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
package com.example.demo;
 
import java.io.Serializable;
 
public class Person implements Serializable {
 
  /**
   *
   */
  private static final long serialVersionUID = 1L;
  private String _id;
  private String _name;
  private String _age;
 
  public String get_id() {
    return _id;
  }
 
  public void set_id(String _id) {
    this._id = _id;
  }
 
  public String get_name() {
    return _name;
  }
 
  public void set_name(String _name) {
    this._name = _name;
  }
 
  public String get_age() {
    return _age;
  }
 
  public void set_age(String _age) {
    this._age = _age;
  }
}

接下來  我們要實現一個ContentHandler 用來解析XML
實現一個ContentHandler 一般需要下面幾個步驟
1、聲明一個類,繼承DefaultHandler。DefaultHandler是一個基類,這個類里面簡單實現了一個ContentHandler。我們只需要重寫里面的方法即可。
2、重寫 startDocument() 和 endDocument(),一般將正式解析之前的初始化放到startDocument()里面,收尾的工作放到endDocument()里面。
3、重寫startElement(),XML解析器遇到XML里面的tag時就會調用這個函數。經常在這個函數內是通過對localName的值進行判斷而操作一些數據。
4、重寫characters()方法,這是一個回調方法。解析器執行完startElement()后,解析節點的內容后就會執行這個方法,并且參數ch[]就是節點的內容。
5、重寫endElement()方法,這個方法與startElement()相對應,解析完一個tag節點后,執行這個方法,解析一個tag后,調用這個處理還原和清除相關信息
首先   新建一個類 繼承DefaultHandler 并重寫以下幾個方法

?
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
public class SAX_parserXML extends DefaultHandler {
 
  /**
   * 當開始解析xml文件的聲明的時候就會觸發這個事件, 可以做一些初始化的工作
   * */
  @Override
  public void startDocument() throws SAXException {
    // TODO Auto-generated method stub
    super.startDocument();
     
  }
 
  /**
   * 當開始解析元素的開始標簽的時候,就會觸發這個事件
   * */
  @Override
  public void startElement(String uri, String localName, String qName,
      Attributes attributes) throws SAXException {
    // TODO Auto-generated method stub
    super.startElement(uri, localName, qName, attributes);
  }
 
  /**
   * 當讀到文本元素的時候要觸發這個事件.
   * */
  @Override
  public void characters(char[] ch, int start, int length)
      throws SAXException {
    // TODO Auto-generated method stub
    super.characters(ch, start, length);
  }
 
  /**
   * 當讀到結束標簽的時候 就會觸發這個事件
   * */
  @Override
  public void endElement(String uri, String localName, String qName)
      throws SAXException {
    // TODO Auto-generated method stub
    super.endElement(uri, localName, qName);
  }
 
}

首先  我們創建一個list  用來保存解析出來的person數據

?
1
List<Person> persons;

但是?在哪里初始化呢?我們可以在startDocument()里面初始化,因為當開始解析xml文件的聲明的時候就會觸發這個事件所以放在這里比較合適

?
1
2
3
4
5
6
7
8
9
10
/**
 * 當開始解析xml文件的聲明的時候就會觸發這個事件, 可以做一些初始化的工作
 * */
@Override
public void startDocument() throws SAXException {
  // TODO Auto-generated method stub
  super.startDocument();
  // 初始化list
  persons = new ArrayList<Person>();
}

接下來  就要開始解析了  

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
/**
   * 當開始解析元素的開始標簽的時候,就會觸發這個事件
   * */
  @Override
  public void startElement(String uri, String localName, String qName,
      Attributes attributes) throws SAXException {
    // TODO Auto-generated method stub
    super.startElement(uri, localName, qName, attributes);
 
    // 如果讀到是person標簽 開始存儲
    if (localName.equals("person")) {
      person = new Person();
      person.set_id(attributes.getValue("id"));
    }
    curNode = localName;
  }

 上面的代碼中  localName表示當前解析到的元素名

?
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
//步驟
//1.判斷是否是person元素
//2.創建新的Person對象
//3.獲取id 添加到Person對象中
curNode 用來保存當前的元素名 在characters中會使用到
/**
   * 當讀到文本元素的時候要觸發這個事件.
   * */
  @Override
  public void characters(char[] ch, int start, int length)
      throws SAXException {
    // TODO Auto-generated method stub
    super.characters(ch, start, length);
 
    if (person != null) {
      //取出目前元素對應的值
      String txt = new String(ch, start, length);
      //判斷元素是否是name
      if (curNode.equals("name")) {
        //將取出的值添加到person對象
        person.set_name(txt);
      } else if (curNode.equals("age")) {
        person.set_age(txt);
      }
    }
  }

接下來是介紹標簽結束的時候需要做的事情

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
/**
 * 當讀到結束標簽的時候 就會觸發這個事件
 * */
@Override
public void endElement(String uri, String localName, String qName)
    throws SAXException {
  // TODO Auto-generated method stub
  super.endElement(uri, localName, qName);
 
  // 如果是 并且person不為空,添加到list
  if (localName.equals("person") && person != null) {
    persons.add(person);
    person = null;
  }
 
  curNode = "";
}

解析的事情結束了  大概流程就是
1.一個元素開始時    會調用startElement方法
2.接下來會調用到characters方法,可以用來獲取元素的值
3.一個元素結束時    會調用到endElement方法
解析結束之后  我們需要寫一個方法  用來獲取解析后保存的list

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
public List<Person> ReadXML(InputStream is) {
 
    SAXParserFactory factory = SAXParserFactory.newInstance();
    try {
      SAXParser parser = factory.newSAXParser();
 
      // 第一種方法
      // parser.parse(is, this);
 
      // 第二種方法
      XMLReader reader = parser.getXMLReader();
      reader.setContentHandler(this);
      reader.parse(new InputSource(is));
 
    } catch (Exception e) {
      // TODO: handle exception
      e.printStackTrace();
    }
 
    return persons;
  }

上面的代碼就不解釋了   只要將inputStream對象傳入  就可以解析出內容
看完了代碼,我來給出完整的代碼

?
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
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
package com.example.demo.Utils;
 
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
 
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
 
import org.xml.sax.Attributes;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;
import org.xml.sax.helpers.DefaultHandler;
 
import com.example.demo.Person;
 
public class SAX_parserXML extends DefaultHandler {
 
  List<Person> persons;
  Person person;
  // 當前節點
  String curNode;
 
  public List<Person> ReadXML(InputStream is) {
 
    SAXParserFactory factory = SAXParserFactory.newInstance();
    try {
      SAXParser parser = factory.newSAXParser();
 
      // 第一種方法
      // parser.parse(is, this);
 
      // 第二種方法
      XMLReader reader = parser.getXMLReader();
      reader.setContentHandler(this);
      reader.parse(new InputSource(is));
 
    } catch (Exception e) {
      // TODO: handle exception
      e.printStackTrace();
    }
 
    return persons;
  }
 
  /**
   * 當開始解析xml文件的聲明的時候就會觸發這個事件, 可以做一些初始化的工作
   * */
  @Override
  public void startDocument() throws SAXException {
    // TODO Auto-generated method stub
    super.startDocument();
    // 初始化list
    persons = new ArrayList<Person>();
  }
 
  /**
   * 當開始解析元素的開始標簽的時候,就會觸發這個事件
   * */
  @Override
  public void startElement(String uri, String localName, String qName,
      Attributes attributes) throws SAXException {
    // TODO Auto-generated method stub
    super.startElement(uri, localName, qName, attributes);
 
    // 如果讀到是person標簽 開始存儲
    if (localName.equals("person")) {
      person = new Person();
      person.set_id(attributes.getValue("id"));
    }
    curNode = localName;
  }
 
  /**
   * 當讀到文本元素的時候要觸發這個事件.
   * */
  @Override
  public void characters(char[] ch, int start, int length)
      throws SAXException {
    // TODO Auto-generated method stub
    super.characters(ch, start, length);
 
    if (person != null) {
      // 取出目前元素對應的值
      String txt = new String(ch, start, length);
      // 判斷元素是否是name
      if (curNode.equals("name")) {
        // 將取出的值添加到person對象
        person.set_name(txt);
      } else if (curNode.equals("age")) {
        person.set_age(txt);
      }
    }
  }
 
  /**
   * 當讀到結束標簽的時候 就會觸發這個事件
   * */
  @Override
  public void endElement(String uri, String localName, String qName)
      throws SAXException {
    // TODO Auto-generated method stub
    super.endElement(uri, localName, qName);
 
    // 如果是person結尾 并且person不為空,添加到list
    if (localName.equals("person") && person != null) {
      persons.add(person);
      person = null;
    }
 
    curNode = "";
  }
 
}

 寫個方法調用下這個類

?
1
2
3
4
5
6
7
8
9
List<Person> persons = new SAX_parserXML().ReadXML(is);
      StringBuffer buffer = new StringBuffer();
      for (int i = 0; i < persons.size(); i++) {
        Person person =persons.get(i);
        buffer.append("id:" + person.get_id() + "  ");
        buffer.append("name:" + person.get_name() + "  ");
        buffer.append("age:" + person.get_age() + "\n");
      }
      Toast.makeText(activity, buffer, Toast.LENGTH_LONG).show();

 如果你看到下面的界面  說明解析成功了~

Java中使用DOM和SAX解析XML文件的方法示例

小結:

DOM(文件對象模型)解析:解析器讀入整個文檔,然后構建一個駐留內存的樹結構,然后代碼就可以根據DOM接口來操作這個樹結構了。 
 
  優點:整個文檔讀入內存,方便操作:支持修改、刪除和重現排列等多種功能。 
 
  缺點:將整個文檔讀入內存中,保留了過多的不需要的節點,浪費內存和空間。 
 
  使用場合:一旦讀入文檔,還需要多次對文檔進行操作,并且在硬件資源充足的情況下(內存,CPU)。 
 
為了解決DOM解析存在的問題,就出現了SAX解析。其特點為: 
 
  優點:不用實現調入整個文檔,占用資源少。尤其在嵌入式環境中,如android,極力推薦使用SAX解析。 
 
  缺點:不像DOM解析一樣將文檔長期駐留在內存中,數據不是持久的。如果事件過后沒有保存數據,數據就會丟失。 
 
  使用場合:機器有性能限制

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 欧美日韩综合精品 | 欧美性网 | 亚洲综合一区二区三区 | 在线一区观看 | 欧美久久久久久久久久 | 中文字幕 亚洲一区 | 国内外成人激情免费视频 | 欧美一级片免费在线观看 | 日韩精品视频在线播放 | 欧美日韩国产一区二区三区 | 欧美一区久久 | 中文字幕国产 | 亚洲国产精品久久久久 | 91资源在线视频 | 色综合视频网 | 亚洲视频 欧美视频 | 国内成人免费视频 | 精品亚洲第一 | 九九热视频精品在线观看 | 亚洲免费色 | 亚洲精品久久久久久一区二区 | 国产9色在线 | 日韩 | 视频一区二区三区中文字幕 | 日本午夜视频 | 欧美日韩一二区 | 综合久久99 | 亚洲国产免费av | 亚洲性人人天天夜夜摸 | 久久成人av| 久草成人网 | 亚洲欧美日韩国产综合精品二区 | 免费黄网站在线观看 | 精品一区二区三区免费 | 日韩精品网站 | 久久成人国产精品 | 免费观看黄色 | 日韩视频精品 | 午夜精品福利网 | 综合久久亚洲 | 午夜视频在线观看免费视频 | 亚洲综合在线网 |