XML的由來
XML是eXtensible Markup Language的縮寫。擴展標記語言XML是一種簡單的數據存儲語言,使用一系列簡單的標記描述數據,而這些標記可以用方便的方式建立,雖然XML占用的空間比二進制數據要占用更多的空間,但XML極其簡單易于掌握和使用
XML是現代程序中一個必不可少的組成部分,也是世界上發展最快的技術之一。它的主要目的是以結構化的方式來表示數據,在某些方面,XML也類似于數據庫,提供數據的結構化視圖。
XML(可擴展標記語言)是從稱為SGML(標準通用標記語言)發展而來的,SGML的主要目的是定義使用標簽來表示數據的標記語言的語法。基于SGML的重要語言之一就是著名的HTML.
標簽由包圍在一個小于號<和一個大于號>之間的文本組成,起始標簽(tag)表示一個特定區域的開始,例如<start>;結束標簽定義了一個區域的結束,除了在小于號之后緊跟一個斜線外和起始標簽一致,例如</end>.舉例說明標簽如下:
<member id=“007”>邦德</member>中,左邊的<member id=“007”>是起始標簽,邦德是標簽中的文字,007是屬性Attribute, </member >是結束標簽.
XML的發展
由于SGML中存在特殊而隨意的語法(如標簽的非嵌套使用),使得建立一個SGML語言的解析器成了一項艱巨的任務,這些困難導致了SGML一直停步不前.
XML通過相對嚴格的語法規定使得建立一個XML解析器要容易得多,這些語法包括:
1)任何起始標簽都必須有一個結束標簽。
2)可以采用另一種簡化語法,可以在一個標簽中同時表示起始和結束標簽。這種語法是在大于符號前緊跟一個斜線/.如<tag />等同于<tag></tag>.
3)標簽必須按照合適的順序進行嵌套,在沒有關閉內部節點之前不能關閉外部節點。
4)所有的特性都必須有值,特性的值周圍應該加上雙引號。
XML文檔示例
<?xml version="1.0" encoding="GBK"?>
<members>
<member name="Andy">
<age>25</age>
<title>JSE</title>
</member>
<member name="Bill">
<age>35</age>
<title>SSE</title>
</member>
<member name="Cindy">
<age>45</age>
<title>PM</title>
</member>
<member name="Douglas">
<age>45</age>
<title>GM</title>
</member>
</members>
<?xml version=“1.0” encoding=“GBK”?>是XML序言,這一行代碼告訴解析器文件將按XML規則進行解析, GBK制定了此文件的編碼方式。
<members>是文檔的根節點,一個XML中有且只有一個根節點,否則會造成解析失敗。
<member name=“Andy”>。。。</member>是根節點下面的子節點,name是其特性,特性的值為Andy。這個子節點下面有age和title兩個子節點。
XML的用途
以文本的形式存儲數據,這樣的形式適于機器閱讀,對于人閱讀也相對方便.
作為程序的配置文件使用,如著名的web.xml,struts-config.xml
Ajax程序傳遞數據的載體.
WebService,SOAP的基礎.
針對XML的API
將XML定義為一種語言之后,就出現了使用常見的編程語言(如Java)來同時表現和處理XML代碼的需求。
首先出現的是Java上的SAX(Simple API for XML)項目。SAX提供了一個基于事件的XML解析的API。從其本質上來說,SAX解析器從文件的開頭出發,從前向后解析,每當遇到起始標簽或者結束標簽、特性、文本或者其他的XML語法時,就會觸發一個事件。然后,當事件發生時,具體要怎么做就由開發人員決定。
因為SAX解析器僅僅按照文本的方式來解析它們,所以SAX更輕量、更快速。而它們的主要缺點是在解析中無法停止、后退或者不從文件開始,直接訪問XML結構中的指定部分。
DOM是針對XML的基于樹的API。它關注的不僅僅是解析XML代碼,而是使用一系列互相關聯的對象來表示這些代碼,而這些對象可以被修改且無需重新解析代碼就能直接訪問它們。
使用DOM,只需解析代碼一次來創建一個樹的模型;某些時候會使用SAX解析器來完成它。在這個初始解析過程之后,XML已經完全通過DOM模型來表現出來,同時也不再需要原始的代碼。盡管DOM比SAX慢很多,而且,因為創建了相當多的對象而需要更多的開銷,但由于它使用上的簡便,因而成為Web瀏覽器和JavaScript最喜歡的方法。
最方便的XML解析利器-dom4j
Dom4j是一個易用的、開源的庫,用于XML,XPath和XSLT。它應用于Java平臺,采用了Java集合框架并完全支持DOM,SAX和JAXP.
sax和dom本身的api都比較復雜,不易使用,而開源包dom4j卻綜合了二者的優點,屏蔽了晦澀的細節,封裝了一系列類和接口以方便用戶使用它來讀寫XML.
Dom4j下載
要使用dom4j讀寫XML文檔,需要先下載dom4j包,dom4j官方網站在 http://www.dom4j.org/ 目前最新dom4j包下載地址:http://nchc.dl.sourceforge.net/sourceforge/dom4j/dom4j-1.6.1.zip
解開后有兩個包,僅操作XML文檔的話把dom4j-1.6.1.jar加入工程就可以了,如果需要使用XPath的話還需要加入包jaxen-1.1-beta-7.jar.
使用dom4j讀寫xml的一些常用對象
1.Document:文檔對象,它代表著整篇xml文檔.
2.Element:節點元素,它代表著xml文檔中的一個節點元素,如前面的<age>25</age>就是一個Element.其值(文本值)為25.
3.Attribute:節點屬性,如前面的節點元素<member name=“Andy”>…< /member >中, name就是節點元素的一個屬性,其值(文本值)為Andy.
與Document對象相關的API
1.讀取XML文件,獲得document對象.
SAXReader reader = new SAXReader();
Document document = reader.read(new File("input.xml"));
2.解析XML形式的文本,得到document對象.
String text = "<members></members>";
Document document = DocumentHelper.parseText(text);
3.主動創建document對象.
Document document = DocumentHelper.createDocument();
Element root = document.addElement("members");// 創建根節點
與Element有關的API
1.獲取文檔的根節點.
Element rootElm = document.getRootElement();
2.取得某節點的單個子節點.
Element memberElm=root.element(“member”);// “member”是節點名
3.取得節點的文字
String text=memberElm.getText();
也可以用:
String text=root.elementText("name");這個是取得根節點下的name字節點的文字.
4.取得某節點下名為"member"的所有字節點并進行遍歷.
List nodes = rootElm.elements("member");
for (Iterator it = nodes.iterator(); it.hasNext();) {
Element elm = (Element) it.next();
// do something
}
5.對某節點下的所有子節點進行遍歷.
for(Iterator it=root.elementIterator();it.hasNext();){
Element element = (Element) it.next();
// do something
}
6.在某節點下添加子節點.
Element ageElm = newMemberElm.addElement("age");
7.設置節點文字.
ageElm.setText("29");
8.刪除某節點.
parentElm.remove(childElm);// childElm是待刪除的節點,parentElm是其父節點
與Attribute相關的API
1.取得某節點下的某屬性
Element root=document.getRootElement();
Attribute attribute=root.attribute("size");// 屬性名name
2.取得屬性的文字
String text=attribute.getText();
也可以用:
String text2=root.element("name").attributeValue("firstname");這個是取得根節點下name字節點的屬性firstname的值.
3.遍歷某節點的所有屬性
Element root=document.getRootElement();
for(Iterator it=root.attributeIterator();it.hasNext();){
Attribute attribute = (Attribute) it.next();
String text=attribute.getText();
System.out.println(text);
}
4.設置某節點的屬性和文字.
newMemberElm.addAttribute("name", "sitinspring");
5.設置屬性的文字
Attribute attribute=root.attribute("name");
attribute.setText("sitinspring");
6.刪除某屬性
Attribute attribute=root.attribute("size");// 屬性名name
root.remove(attribute);
將document的內容寫入XML文件
1.文檔中全為英文,不設置編碼,直接寫入的形式.
XMLWriter writer = new XMLWriter(new FileWriter("output.xml"));
writer.write(document);
writer.close();
2.文檔中含有中文,設置編碼格式寫入的形式.
OutputFormat format = OutputFormat.createPrettyPrint();
format.setEncoding("GBK"); // 指定XML編碼
XMLWriter writer = new XMLWriter(new FileWriter("output.xml"),format);
writer.write(document);
writer.close();
字符串與XML的轉換
1.將字符串轉化為XML
String text = "<members> <member>sitinspring</member> </members>";
Document document = DocumentHelper.parseText(text);
2.將文檔或節點的XML轉化為字符串.
SAXReader reader = new SAXReader();
Document document = reader.read(new File("input.xml"));
Element root=document.getRootElement();
String docXmlText=document.asXML();
String rootXmlText=root.asXML();
Element memberElm=root.element("member");
String memberXmlText=memberElm.asXML();
使用XPath快速找到節點.
讀取的XML文檔示例
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>MemberManagement</name>
<comment></comment>
<projects>
<project>PRJ1</project>
<project>PRJ2</project>
<project>PRJ3</project>
<project>PRJ4</project>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.jdt.core.javanature</nature>
</natures>
</projectDescription>
使用XPath快速找到節點project.
public static void main(String[] args){
SAXReader reader = new SAXReader();
try{
Document doc = reader.read(new File("sample.xml"));
List projects=doc.selectNodes("/projectDescription/projects/project");
Iterator it=projects.iterator();
while(it.hasNext()){
Element elm=(Element)it.next();
System.out.println(elm.getText());
}
}
catch(Exception ex){
ex.printStackTrace();
}
}