国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

java拾遺1----XML解析(一) DOM解析

2019-11-15 00:48:57
字體:
來源:轉載
供稿:網友
java拾遺1----xml解析(一) DOM解析

XML解析技術主要有三種:

(1)DOM(Document Object Model)文檔對象模型:是 W3C 組織推薦的解析XML 的一種方式,即官方的XML解析技術。

(2)SAX(Simple Api for XML)產生自 XML 社區,幾乎所有的 XML 解析器都支持它。

(3)StAX(Stream Api for XML)一種拉模式處理XML文檔的API。

DOM解析技術

DOM解析XML的做法是將整個XML 加載內存中,形成以樹形結構存儲的文檔對象,所有對XML的操作都對內存中文檔對象進行。

DOM解析的特點是要將整個XML文檔加載到內存中,若文檔比較大,則會占用很大的內存空間,但是由于整個文檔都在內存中,可以方便地進行修改回寫操作。

SAX解析技術

當XML 文檔非常大時,將整個文檔加載到內存中進行解析,可能會造成內存溢出,而且很多時候只是對文檔中的部分節點進行操作,加載整個文檔會導致工作效率的低下。SAX的思想是一邊解析XML,然后對解析的部分進行相關處理,然后釋放已處理完成的部分所占用的內存資源。SAX是一種推模式XML解析方式,由服務端主導,向客戶端推送數據。

StAX解析技術

基本同SAX,不同之處在于,StAX是一種拉模式的XML解析技術,由客戶端主導,從服務端拉取要解析的數據。Android系統中內置使用該種方式解析XML。

SAX與StAX的相同之處在于:相比DOM是一種更為輕量級的方案,采用串行方法讀取 --- 文件輸入流(字節、字符)讀取,但是會導致編程較為復雜,且無法在讀取過程中修改XML數據。

常見的XML解析開發包

JAXP 是sun官方推出實現技術,同時支持DOM、 SAX、 StAX。

DOM4j 是開源社區開源框架,支持DOM解析方式。

XML PULL是 Android 移動設備內置xml 解析技術,支持StAX解析方式。

XML的DOM解析方式

直接使用JDK自帶的JAXP進行xml解析,所用到的相關類都存放在以下幾個包中:

javax.xml.parsers 存放 DOM 和 SAX 解析器

javax.xml.stream 存放 STAX 解析相關類

org.w3c.dom 存放DOM解析時的數據節點類

org.xml.sax 存放SAX解析相關工具類

(一)加載解析XML文檔

要解析一個XML文檔,首先需要加載該文檔

javax.xml.parsers中的DocumentBuilderFactory工廠類可以獲取生成 DOM 對象樹的解析器。

獲得該類實例的方法是,調用該類的newInstance()方法。之后通過調用工廠類對象的newDocumentBuilder()方法便可以獲取了DocumentBuilder這個DOM的XML解析器。

調用DocumentBuilder的parse()方法,便可以將XML文件解析為Document對象。

如:新建一個DomXmlParser類,添加一個loadFromFile方法:

 1 public class DomXmlParser { 2  3          public static Document loadFromFile(String filename) throws Exception{ 4  5                    DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); 6  7                    DocumentBuilder builder = factory.newDocumentBuilder(); 8  9                    Document document = builder.parse(filename);10 11                    return document;12 13          }14 15 }

注意,Document導包時,一定要是org.w3c.dom。

Document 接口表示整個 HTML 或 XML 文檔。從概念上講,它是文檔樹的根,并提供對文檔數據的基本訪問。

常用方法:

NodeList getElementsByTagName(String tagname):按文檔順序返回包含在文檔中且具有給定標記名稱的所有Element的NodeList。

Element getElementById(String elementId):返回具有帶給定值的 ID 屬性的 Element。注意,該方法只有在XML文檔具有約束時才可以使用,所以一般沒有帶有約束的不會用到該方法。

NodeList 接口提供對節點的有序集合的抽象,沒有定義或約束如何實現此集合。DOM 中的 NodeList 對象是活動的,刪除某個元素時,會導致后續元素向前移動,即下標減一。NodeList 中的項可以通過從 0 開始的整數索引進行訪問。

常用方法:

int getLength()列表中的節點數。

Node item(int index)返回集合中的第 index 個元素。

Node 接口是整個文檔對象模型的主要數據類型。它表示該文檔樹中的單個節點。

幾個主要的子接口:

Document:上面已然提到

Element:表示 HTML 或 XML 文檔中的一個元素。

Attr :表示 Element 對象中的屬性。

Text :并且表示 Element 或 Attr 的文本內容(在 XML 中稱為字符數據)。

Comment:表示注釋的內容

如有下面xml文檔:

 1 <?xml version="1.0" encoding="UTF-8"?> 2  3 <students> 4  5     <student id="001"> 6  7         <name>zhangsan</name> 8  9         <gender>male</gender>10 11         <age>23</age>12 13     </student>14 15     <student id="002">16 17         <name>lisi</name>18 19         <gender>male</gender>20 21         <age>24</age>22 23     </student>24 25     <student id="003">26 27         <name>xiaoqiao</name>28 29         <gender>female</gender>30 31         <age>18</age>32 33     </student>34 35     <student id="004">36 37         <name>diaochan</name>38 39         <gender>female</gender>40 41         <age>23</age>42 43     </student>44 45 </students>

各個節點的類型就是Element,節點的屬性id就是Attr,節點中的值如femal、lisi等就是Text。

Node接口中提供了獲取Node各種屬性的方法,以及通過相對位置獲取其他Node的方法,具體可以查看API幫助手冊。

常用的有這么幾個:

NodeList getChildNodes():包含此節點的所有子節點的 NodeList。

Node getFirstChild()此節點的第一個子節點。

Node getLastChild()此節點的最后一個節點。

Node getNextSibling()直接在此節點之后的節點。

Node getParentNode()此節點的父節點。

Node getPReviousSibling()直接在此節點之前的節點。

String getTextContent()此屬性返回此節點及其后代的文本內容。

如,要輸出所有學生的姓名:

DomXmlParser類:

 1 public class DomXmlParser { 2  3          protected static Document document = null; 4  5          public static Document loadFromFile(String filename) throws Exception{ 6  7                    DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); 8  9                    DocumentBuilder builder = factory.newDocumentBuilder();10 11                    document = builder.parse(filename);12 13                    return document;14 15          }16 17 }

StudentParser類:

 1 public class StudentParser extends DomXmlParser { 2  3          public static String[] getAllNames(){ 4  5                    NodeList students = document.getElementsByTagName("student"); 6  7                    String[] names = new String[students.getLength()]; 8  9                    for (int i = 0; i < students.getLength(); i++) {10 11                             Element stu = (Element) students.item(i);12 13                             names[i] = stu.getChildNodes().item(1).getTextContent();14 15                    }16 17                    return names;18 19          }20 21 }

getChildNodes()方法用于獲取所有的子元素,返回一個NodeList對象。

如果對當前xml文檔中的每一個student節點調用該方法獲取子元素,會發現返回的NodeList中元素數目為7。

1 <student id="001">2 3         <name>zhangsan</name>4 5         <gender>male</gender>6 7         <age>23</age>8 9 </student>

這是因為:每個回車換行被當做Text節點。一個student節點有4個回車換行節點以及<name>、<gender>、<age>這3個Element節點,所以總共有7個節點。

而對于<name>節點來說,則只有一個子節點,該節點是Text節點。

(二)修改回寫

當完成了對XML的相關處理工作后,可以將修改寫回到xml文檔中,與加載解析相似,回寫也需要相應的工廠類,相應的轉換類。

 1 //獲取Transformer工廠類實例 2  3 TransformerFactory transformerFactory = TransformerFactory.newInstance(); 4  5 //通過工廠類獲取Transformer實例 6  7 Transformer transformer = transformerFactory.newTransformer(); 8  9 //選擇要回寫的內存中的document對象10 11 DOMSource domSource = new DOMSource(document);12 13 //要回寫的目標文件14 15 StreamResult result = new StreamResult(new File("students_bak.xml"));16 17 //將內存DOM對象回寫到文件中18 19 transformer.transform(domSource, result);

例如:

在DomXmlParser類中添加方法:

 1 public static boolean saveAs(String filename) throws Exception{ 2  3                    TransformerFactory factory = TransformerFactory.newInstance(); 4  5                    transformer = factory.newTransformer(); 6  7                    DOMSource source = new DOMSource(document); 8  9                    StreamResult target = new StreamResult(new File(filename));10 11                    transformer.transform(source, target);12 13                    return true;14 15 }

調用:

 1 public static void main(String[] args) { 2  3                    // TODO Auto-generated method stub 4  5                    try { 6  7                             StudentParser.loadFromFile("students.xml"); 8  9                             String[] names = StudentParser.getAllNames();10 11                             for (int i = 0; i < names.length; i++) {12 13                                      System.out.println(names[i]);14 15                             }16 17                             StudentParser.saveAs("students_bak.xml");18 19                    } catch (Exception e) {20 21                             // TODO Auto-generated catch block22 23                             e.printStackTrace();24 25                    }26 27 }

使用DOM解析XML實現完整的增刪改查操作示例:

首先需要一個Student類:

 1 package cn.csc.bean; 2  3 public class Student { 4  5          private String id = null; 6  7          private String name = null; 8  9          private String gender = null;10 11          private int age = 0;12 13          public String getId() {14 15                    return id;16 17          }18 19          public void setId(String id) {20 21                    this.id = id;22 23          }24 25          public String getName() {26 27                    return name;28 29          }30 31          public void setName(String name) {32 33                    this.name = name;34 35          }36 37          public String getGender() {38 39                    return gender;40 41          }42 43          public void setGender(String gender) {44 45                    this.gender = gender;46 47          }48 49          public int getAge() {50 51                    return age;52 53          }54 55          public void setAge(int age) {56 57                    this.age = age;58 59          }60 61          public Student(String id, String name, String gender, int age) {62 63                    super();64 65                    this.id = id;66 67                    this.name = name;68 69                    this.gender = gender;70 71                    this.age = age;72 73          }74 75          public Student() {76 77                    super();78 79          }80 81          public String toString() {82 83                    return "[id:"+id+",name:"+name+",gender:"+gender+",age"+age+"]";84 85          }86 }

1)通過id獲取學生信息:

在StudentParser類中添加getStudentById(String id)方法:

 1 public static Student getStudentById(String id){ 2  3                    Student student = null; 4  5                    NodeList students = document.getElementsByTagName("student"); 6  7                    for(int i=0; i<students.getLength(); i++){ 8  9                             Element stu = (Element) students.item(i);10 11                             if(stu.getAttribute("id").equals(id)){12 13                                      student = new Student();14 15                                      student.setName(((Element)stu.getElementsByTagName("name").item(0)).getTextContent());16 17                                      student.setGender(((Element)stu.getElementsByTagName("gender").item(0)).getTextContent());18 19                                      String age = ((Element)stu.getElementsByTagName("age").item(0)).getTextContent();20 21                                      student.setAge(Integer.parseInt(age));22 23                                      student.setId(id);24 25                                      return student;26 27                             }28 29                    }30 31                    return student;32 33 }

調用該方法:

1 StudentParser.loadFromFile("students.xml");2 3 System.out.println(StudentParser.getStudentById("001"));

輸出結果:

[id:001,name:zhangsan,gender:male,age23]

2)通過性別查找學生:

在StudentParser類中添加getStudentsByGender(String gender)方法:

 1 public static List<Student> getStudentsByGender(String gender){ 2  3                    List<Student> stus = new ArrayList<Student>(); 4  5                    Student tmp = null; 6  7                    NodeList students = document.getElementsByTagName("student"); 8  9                    for(int i=0; i<students.getLength(); i++){10 11                             Element stu = (Element) students.item(i);12 13                             Element gen = (Element)stu.getElementsByTagName("gender").item(0);14 15                             if(gen.getTextContent().equals(gender)){16 17                                      tmp = new Student();18 19                                      tmp.setGender(gender);20 21                                      Element name = (Element) gen.getPreviousSibling().getPreviousSibling();22 23                                      tmp.setName(name.getTextContent());24 25                                      Element age = (Element) gen.getNextSibling().getNextSibling();26 27                                      tmp.setAge(Integer.parseInt(age.getTextContent()));28 29                                      tmp.setId(stu.getAttribute("id"));30 31                                      stus.add(tmp);32 33                             }34 35                    }36 37                    return stus;38 39 }

注意:回車換行作為Text節點的問題是上面連著調用兩次getNextSibling()和getPreviousSibling()的原因所在。

調用:

1 StudentParser.loadFromFile("students.xml");2 3 List<Student> students = StudentParser.getStudentsByGender("female");4 5 for (int i = 0; i < students.size(); i++) {6 7          System.out.println(students.get(i));8 9 }

輸出結果:

[id:003,name:xiaoqiao,gender:female,age18]

[id:004,name:diaochan,gender:female,age23]

3)添加一條學生信息:

 1 public static boolean insert(Student stu){ 2  3                    Element root = (Element) document.getElementsByTagName("students").item(0); 4  5                    Element student = document.createElement("student"); 6  7                    student.setAttribute("id", stu.getId()); 8  9                    Element name = document.createElement("name");10 11                    name.setTextContent(stu.getName());12 13                    Element gender = document.createElement("gender");14 15                    gender.setTextContent(stu.getGender());16 17                    Element age = document.createElement("age");18 19                    age.setTextContent(stu.getAge()+"");20 21                    student.appendChild(name);22 23                    student.appendChild(gender);24 25                    student.appendChild(age);26 27                    root.appendChild(student);28 29                    try {30 31                             saveAs("students.xml");32 33                    } catch (Exception e) {34 35                             // TODO Auto-generated catch block36 37                             e.printStackTrace();38 39                             return false;40 41                    }42 43                    return true;44 45 }

添加之后,一定要記得回寫。

調用:

1 StudentParser.loadFromFile("students.xml");2 3 StudentParser.insert(new Student("005","dqrcsc","male",25));

4)根據id修改學生信息:

 1 public static boolean update(String id, Student stu){ 2  3                    NodeList stus = document.getElementsByTagName("student"); 4  5                    for(int i=0; i<stus.getLength(); i++){ 6  7                             Element tmp = (Element) stus.item(i); 8  9                             if(tmp.getAttribute("id").equals(id)){10 11                                      tmp.setAttribute("id", stu.getId());12 13                                      tmp.getChildNodes().item(1).setTextContent(stu.getName());14 15                                      tmp.getChildNodes().item(3).setTextContent(stu.getGender());16 17                                      tmp.getChildNodes().item(5).setTextContent(stu.getAge()+"");18 19                                      try {20 21                                                saveAs("students.xml");22 23                                      } catch (Exception e) {24 25                                                // TODO Auto-generated catch block26 27                                                e.printStackTrace();28 29                                                return false;30 31                                      }32 33                                      return true;34 35                             }36 37                    }38 39                   40 41                    return false;42 43 }

調用:

1 StudentParser.update("001", new Student("000","zhangsan22","female",26));

5)根據年齡刪除學生信息:

 1 public static int deleteStudentsOlderThan(int age){ 2  3                    int cnt = 0; 4  5                    NodeList stus = document.getElementsByTagName("student"); 6  7                    Element root = document.getDocumentElement(); 8  9                    for(int i = stus.getLength()-1; i>=0; i--){10 11                             Element tmp = (Element) stus.item(i);12 13                             String str = tmp.getChildNodes().item(5).getTextContent();14 15                             int a = Integer.parseInt(str);16 17                             if(a>=age){18 19                                      root.removeChild(tmp);20 21                                      cnt++;22 23                             }24 25                    }26 27                    try {28 29                             saveAs("students_bak.xml");30 31                    } catch (Exception e) {32 33                             // TODO Auto-generated catch block34 35                             e.printStackTrace();36 37                    }38 39                    return cnt;40 41 }

調用:

1 System.out.println(StudentParser.deleteStudentsOlderThan(22));


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 台安县| 高清| 昂仁县| 准格尔旗| 芒康县| 平阳县| 临猗县| 杨浦区| 松阳县| 岑溪市| 南汇区| 昔阳县| 镇坪县| 新竹市| 万全县| 临澧县| 增城市| 青阳县| 新巴尔虎右旗| 大埔区| 嘉禾县| 积石山| 东阳市| 宁乡县| 凤城市| 富阳市| 松滋市| 马关县| 泽库县| 黔东| 综艺| 北川| 财经| 尉犁县| 桐梓县| 旌德县| 丹江口市| 泊头市| 辽源市| 青神县| 临西县|