java中的xml简介与DOM解析xml

1. xml简介

  XML:指可扩展标记语言, Extensible Markup Language;类似HTML。XML的设计宗旨是传输数据,而非显示数据。

  一个xml文档实例:

 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <company name="Tencent" address="深圳市南山区">
 3   <department deptNo="001" name="development">
 4     <employee id="devHead" position="minister">许刚</employee>
 5     <employee position="developer">工程师A</employee>
 6   </department>
 7   <department deptNo="002" name="education">
 8     <employee position="minister" telephone="1234567">申林</employee>
 9     <employee position="trainee">实习生A</employee>
10   </department>
11 </company>

  第一行是 XML 声明。它定义 XML 的版本 (1.0) 和所使用的编码.

  下一行描述文档的根元素:<company>开始,该根元素具有2个属性“name”,"address"。

  最后一行定义根元素的结尾。</company>。

    

  · XML 文档形成一种树结构

  · XML 文档必须包含根元素。该元素是所有其他元素的父元素。

  · XML 文档中的元素形成了一棵文档树。这棵树从根部开始,并扩展到树的最底端。

所有元素均可拥有子元素: 

1 <root>
2 
3   <child>
4 
5     <subchild>.....</subchild>
6 
7   </child>
8 
9 </root>

  父、子以及同胞等术语用于描述元素之间的关系。父元素拥有子元素。相同层级上的子元素成为同胞(兄弟或姐妹)。

 

1.1 节点

  节点:XML文档中的所有节点组成了一个文档树(或节点树)。XML文档中的每个元素、属性、文本等都代表着树中的一个节点。树起始于文档节点,并由此继续伸出枝条,直到处于这棵树最低级别的所有文本节点为止,常用节点类型如下表所示:

节点类型

附加说明

实例

元素节点(Element)

XML标记元素

<company>…</company>

属性节点(Attribute)

XML标记元素的属性

name=”Tencent”

文本节点(Text)

包括在XML标记中的文本段

工程师A

文档类型节点(DocumentType)

文档类型声明

﹤!DOCTYPE…﹥

注释节点Comment

XmlComment类注释节点。

<!—文档注释->

 

 

(1) 节点关系

  通过上面的XML文档,我们构建出如下树状文档对象模型:

  

 1 <?xml version="1.0" encoding="UTF-8"?>    
 2 <bookstore>
 3 <book category="COOKING">
 4   <title lang="en">Everyday Italian</title> 
 5   <author>Giada De Laurentiis</author> 
 6   <year>2005</year> 
 7   <price>30.00</price> 
 8 </book>
 9 <book category="CHILDREN">
10   <title lang="en">Harry Potter</title> 
11   <author>J K. Rowling</author> 
12   <year>2005</year> 
13   <price>29.99</price> 
14 </book>
15 <book category="WEB">
16   <title lang="en">Learning XML</title> 
17   <author>Erik T. Ray</author> 
18   <year>2003</year> 
19   <price>39.95</price> 
20 </book>
21 </bookstore>

  再如上例xml文档:

  例子中的根元素是 <bookstore>。文档中的所有 <book> 元素都被包含在 <bookstore> 中。<book> 元素有 4 个子元素:<title>、< author>、<year>、<price>。

 

(2)xml的特点

  a). XML 的属性值须加引号。

  · 与 HTML 类似,XML 也可拥有属性(名称/值的对)。

  · 在 XML 中,XML 的属性值须加引号。

  b). XML 文档必须有根元素.XML 文档必须有一个元素是所有其他元素的父元素。该元素称为根元素

  c). XML 标签对大小写敏感.

  · XML 元素使用 XML 标签进行定义。

  · XML 标签对大小写敏感。在 XML 中,标签 <Letter> 与标签 <letter> 是不同的。必须使用相同的大小写来编写打开标签和关闭标签。

  d). XML 中的注释语法: 

<!-- This is a comment --> 

 

  e). XML 元素 vs. 属性

 

 1 <person sex="female">
 2   <firstname>Anna</firstname>
 3   <lastname>Smith</lastname>
 4 </person> 
 5 
 6 <person>
 7   <sex>female</sex>
 8   <firstname>Anna</firstname>
 9   <lastname>Smith</lastname>
10 </person> 

 

  在第一行中,sex 是一个属性。在第7行中,sex 则是一个子元素。两个例子均可提供相同的信息。

 

2. xml 解析

  xml解析方法有四种:  

  · DOM(JAXP Crimson 解析器):W3C为HTML和XML分析器制定的标准接口规范,基于树,可随机动态访问和更新文档的内容、结构、样式。

 

   · SAX(simple API for XML):不是W3C的标准,而是由XML-DEV邮件列表成员于1998年为Java语言开发的一种基于事件的简单API。基于事件,逐行解析,顺序访问XML文档,速度快,处理功能简单。

 

   · JDOM:鉴于DOM的低效率,而SAX又不能随机处理XML文档,Jason Hunter与Brett McLaughlin于2000年春天,开始创建一种能充分体现两者优势的API——JDOM(Java-based DOM,基于Java的DOM),它是一个基于Java的对象模型,树状结构,能使读取、操作和写入XML文档,比DOM更高效,比SAX更强大,但由于使用了大量的类而不使用接口导致灵活性降低。

 

  · DOM4J:DOM4J是一个易用的,开源的库,用于XML,XPath,XSLT。它应用于Java平台,采用了Java集合框架并完全支持DOM,SAX,JAXP。它提供了大量的接口,因此比JDOM更具有灵活性。

 

2.1 DOM解析xml

  DOM(Document Object Model文档对象模型),是W3C为HTML和XML分析器制定的标准接口规范。   

特点:独立于语言,跨平台(可以在各种编程和脚本语言中使用),需要将整个文档读入内存,在内存中创建文档树,可随即访问文档中的特定节点,对内存的要求比较高,经过测试,访问速度相对于其他解析方式较慢,适用于简单文档的随即处理

 

常用的节点属性:

属性

描述

nodeName

结点名称

nodeValue

结点内部值,通常只应用于文本结点

nodeType

节点类型对应的数字

parentNode

如果存在,指向当前结点的父亲结点

childNodes

子结点列表

firstChild

如果存在,指向当前元素的第一个子结点

lastChild

如果存在,指向当前元素的最后一个子结点

previousSibling

指向当前结点的前一个兄弟结点

nextSibling

指向当前结点的后一个兄弟结点

attributes

元素的属性列表

 常用的节点方法:

  

操作类型

方法原型

描述

访问节点

getElementById(id)

根据ID属性查找元素节点

getElementsByName(name)

根据name属性查找元素集

getElementsByTagName(tagName)

根据元素标记名称查找元素集

创建节点

createElement(tagName)

创建元素节点

createTestNode(string)

创建文本节点

createAttribute(name)

创建属性节点

插入和添加节点

appendChild(newChild)

添加子节点到目标节点上

insertBefore(newChild,targetChild)

将newChild节点插入到targetChild节点之前

复制节点

CloneNode(bool)

复制该节点,由bool确定是否复制子节点

删除和替换节点

removeChild(childName)

删除由childName指定的节点

replaceChild(newChild,oldChild)

用newChild替换oldChild

属性节点操作

getAttribute(name)

返回目标对象指定属性名称为name的属性值

setAttribute(name,value)

修改目标节点指定属性名称为name的属性值为value

removeAttribute(name)

删除目标节点指定属性名称为name的属性

 (1)读取本地xml文档解析为对象的步骤: 

  * 首先利用DocumentBuilderFactory创建一个DocumentBuilderFactory实例;然后利用DocumentBuilderFactory创建DocumentBuilder

//创建DocumentBuilderFactory工厂实例。
DocumentBuilderFactory dbfactory = DocumentBuilderFactory.newInstance();
//通过文档创建工厂创建文档创建器
DocumentBuilder dBuilder = dbfactory.newDocumentBuilder();

  * 然后加载XML文档(Document)  : 通过文档创建器DocumentBuilder的parse方法解析参数URL指定的XML文档,并返回一个Document 对象。

Document doc = dBuilder.parse(url);

  * 然后获取文档的根结点(Element),
  * 然后获取根结点中所有子节点的列表(NodeList),
  * 然后使用再获取子节点列表中的需要读取的结点。

 

实例:

books.xml:

 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <bookstore>
 3 <book category="COOKING">
 4     <title lang="en">Everyday Italian</title>
 5     <author>Giada De Laurentiis</author>
 6     <year>2005</year>
 7     <price>30.0</price>
 8 </book>
 9 <book category="CHILDREN">
10     <title lang="en">Harry Potter</title>
11     <author>J K. Rowling</author>
12     <year>2005</year>
13     <price>29.99</price>
14 </book>
15 <book category="WEB">
16     <title lang="en">Learing XML</title>
17     <author>Erik T. Ray</author>
18     <year>2010</year>
19     <price>48.99</price>
20 </book>
21 </bookstore>

Books抽象类:

 1 package demo;
 2 
 3 /**
 4  * 根据xml “books”文档,新创建Books类
 5  * Created by luts on 2015/12/18.
 6  */
 7 public class Books {
 8     private String category;
 9     private String title;
10     private String language;
11     private String author;
12     private String year;
13     private String price;
14 
15     public String getCategory() {
16         return category;
17     }
18 
19     public void setCategory(String category) {
20         this.category = category;
21     }
22 
23     public String getTitle() {
24         return title;
25     }
26 
27     public void setTitle(String title) {
28         this.title = title;
29     }
30 
31     public String getLanguage() {
32         return language;
33     }
34 
35     public void setLanguage(String language) {
36         this.language = language;
37     }
38 
39     public String getAuthor() {
40         return author;
41     }
42 
43     public void setAuthor(String author) {
44         this.author = author;
45     }
46 
47     public String getYear() {
48         return year;
49     }
50 
51     public void setYear(String year) {
52         this.year = year;
53     }
54 
55     public String getPrice() {
56         return price;
57     }
58 
59     public void setPrice(String price) {
60         this.price = price;
61     }
62 }

DOM解析:

  1 package demo;
  2 
  3 import org.w3c.dom.*;
  4 import org.xml.sax.SAXException;
  5 
  6 import javax.xml.parsers.DocumentBuilder;
  7 import javax.xml.parsers.DocumentBuilderFactory;
  8 import javax.xml.parsers.ParserConfigurationException;
  9 import java.awt.print.Book;
 10 import java.io.FileNotFoundException;
 11 import java.io.IOException;
 12 import java.util.ArrayList;
 13 import java.util.List;
 14 
 15 /**
 16  * Created by luts on 2015/12/18.
 17  */
 18 public class DOMTest {
 19     public static void main(String[] args){
 20 
 21         List<Books> books = new ArrayList<Books>();
 22 
 23         Books book = null;
 24 
 25         try {
 26             DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
 27             DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
 28             Document document = dBuilder.parse("src/books.xml");
 29             //找到根节点
 30             Element root = document.getDocumentElement();
 31 
 32             System.out.println("------开始解析-------");
 33             NodeList booksList = root.getElementsByTagName("book");
 34             System.out.println("一共有" + booksList.getLength() + "本书");
 35             //遍历book节点的所有节点
 36             for (int i = 0; i < booksList.getLength(); i++){
 37                 book = new Books();
 38 
 39                 System.out.println("-----现在开始遍历第" +(i + 1) +  "本书的内容-----");
 40                 //通过item(i)方法获取一个book节点
 41                 Node nodeBook = booksList.item(i);
 42                 //获取book节点的所有属性集合
 43                 NamedNodeMap attrs = nodeBook.getAttributes();
 44                 System.out.println("第" + (i + 1) + "本书有"+ attrs.getLength() + "个属性");
 45 
 46                 //遍历book属性
 47                 for (int j = 0; j < attrs.getLength(); j++){
 48                     //通过item(index)方法获取book节点的某一个属性
 49                     Node attr = attrs.item(j);
 50                     //获取属性名和属性值
 51                     System.out.println("属性名:" + attr.getNodeName() + ", 属性值:" + attr.getNodeValue());
 52                     book.setCategory(attr.getNodeValue());
 53 
 54                 }
 55 
 56 
 57                 /*
 58                 //如果book节点有且只有一个category属性,可以通过将book节点进行强制类型转换,转换成Element类型。
 59                 Element bookElement = (Element) booksList.item(i);
 60                 //通过getAttribute("category")
 61                 String attrVaule = bookElement.getAttribute("category");
 62                 System.out.println("category的属性值为" + attrVaule);
 63                 */
 64 
 65                 //解析book节点的子节点
 66                 NodeList bookchildNode = nodeBook.getChildNodes();
 67                 //遍历bookchildNode获取每个节点的节点名和节点值
 68                 System.out.println("第" + (i +1) + "本书共有" + bookchildNode.getLength() + "个子节点");
 69 
 70                 for (int k = 0; k < bookchildNode.getLength(); k++){
 71 
 72                     //区分text类型的node和element类型的node
 73                     if (bookchildNode.item(k).getNodeType() == Node.ELEMENT_NODE){
 74                         //获取element类型的节点
 75                         System.out.println("\t第" + (k+1)+ "个节点的节点名:" + bookchildNode.item(k).getNodeName());
 76                         //获取element类型的节点值
 77                         System.out.println("\t节点值:" + bookchildNode.item(k).getFirstChild().getNodeValue());
 78                        // System.out.println("--节点值是:" + bookchildNode.item(k).getTextContent());
 79 
 80                         if(bookchildNode.item(k).getNodeName().equals("title")){
 81                             book.setTitle(bookchildNode.item(k).getFirstChild().getNodeValue());
 82                             Element nodeLang = (Element)  (bookchildNode.item(k));
 83                             String lang = nodeLang.getAttribute("lang");
 84                             book.setLanguage(lang);
 85 
 86                         }
 87 
 88                         if(bookchildNode.item(k).getNodeName().equals("author")){
 89                             book.setAuthor(bookchildNode.item(k).getFirstChild().getNodeValue());
 90                         }
 91 
 92                         if(bookchildNode.item(k).getNodeName().equals("year")){
 93                             book.setYear(bookchildNode.item(k).getFirstChild().getNodeValue());
 94                         }
 95 
 96                         if(bookchildNode.item(k).getNodeName().equals("price")){
 97                             book.setPrice(bookchildNode.item(k).getFirstChild().getNodeValue());
 98                         }
 99 
100                     }
101                 }
102 
103                 books.add(book);
104                 System.out.println("-----结束遍历第" + (i+1)+"本书的内容------");
105 
106             }
107             System.out.println("------解析完毕!------");
108         }
109         catch (FileNotFoundException e){
110             System.out.println(e.getMessage());
111         }catch (ParserConfigurationException e){
112             System.out.println(e.getMessage());
113         }catch (SAXException e){
114             System.out.println(e.getMessage());
115         }catch (IOException e){
116             System.out.println(e.getMessage());
117         }
118 
119         //输出bookList中的book
120         for(int m = 0; m < books.size(); m++){
121             System.out.println("总共有" + books.size() + "本书");
122             Books bookElemntTemp = (Books)books.get(m);
123             System.out.println("第"+(m + 1) + "本书的分类:" + bookElemntTemp.getCategory() + ", 作者:" + bookElemntTemp.getAuthor() + "语言: " +bookElemntTemp.getLanguage());
124 
125         }
126     }
127 
128 
129 
130 }

结果:

posted on 2015-12-18 15:16  Luts  阅读(3879)  评论(0编辑  收藏  举报