XML 技術是隨着 Java 的發展而發展起來的。在 XML 出現以前對於簡單的數據格式一般是存儲在 ini 配置文件等文本文件中,複雜的格式則採用自定義的文件格式,所以對於每種文件格式都要有專門的解析程序。 XML 出現之後解決了這個問題,程序面對的是有固定格式的 XML 文件,只要經過標準 API 就能夠進行 XML 文件的處理。
XML 文件在案例系統中應用是很普遍的,好比 ClientConfig.xml 、 ServerConfig.xml 文件就是使用 XML 文件來作配置文件的,元數據文件以及元數據加載器更是離不開 XML 。所以總結一下處理技術。java
XML處理技術比較node
在 Java 領域 XML 文件的技術大體分爲兩類: XML API 和 OXMapping 。 XML API 是 XML 處理的基礎,可選技術包括 JDOM 、 Dom4j 等; OXMapping 是 Object-XML Mapping 的簡稱,這種技術隱藏了 XML 底層操做的細節,能夠將 XML 文件映射成一個 JavaBean 對象,也能夠把一個 JavaBean 對象保存成一個 XML 文件,可選技術 XStream 、 Digester 、 Castor 等。 XML API 和 OXMapping 的關係相似於 JDBC 和 ORMaping 的關係, OXMapping 內部實現使用 XML API 來完成,兩種實現技術從不一樣的層面實現了 XML 的處理。設計模式
XML API
此類 XML 處理技術中最流行的莫過於 JDOM 和 Dom4j 了,兩者的使用方式很是類似。不過 Dom4j 的優點比 JDOM 更明顯一些:
DOM4J是dom4j.org出品的一個開源XML解析包,它的網站中這樣定義:
Dom4j是一個易用的、開源的庫,用於XML,XPath和XSLT。它應用於Java平臺,採用了Java集合框架並徹底支持DOM,SAX和JAXP。
DOM4J使用起來很是簡單。只要你瞭解基本的XML-DOM模型,就能使用。
dom4j是sourceforge.net上的一個開源項目,主要用於對XML的解析。從2001年7月發佈初版以來,已陸續推出多個版本。
dom4j專門針對Java開發,使用起來很是簡單、直觀,在Java界,dom4j正迅速普及。
能夠到http://sourceforge.net/projects/dom4j下載其最新版。
dom4j1.5的完整版大約13M,是一個名爲dom4j-1.5.zip的壓縮包,解壓後有一個dom4j-1.5.jar文件,這就是應用時須要引入的類包,另外還有一個jaxen-1.1-beta-4.jar文件,通常也須要引入,不然執行時可能拋java.lang.NoClassDefFoundError: org/jaxen/JaxenException異常,其餘的包能夠選擇用之。api
Dom4j 支持 XPath 等高級特性;
正是因爲這些優勢,不少開源項目都開始使用 Dom4j 作 XML 解析技術,本書也將使用 Dom4j 作爲 XML 處理的首選。
OXMapping
使用 XML API 解析是略顯煩瑣的,受 ORMapping 技術的啓發,人們發明了 OXMapping 技術,使用 OXMapping 技術,咱們能夠將 XML 文件映射成一個 JavaBean 對象,也能夠把一個 JavaBean 對象保存成一個 XML 文件,這大大簡化了咱們的開發工做量,使得開發人員能更多的關注應用層面的東西。app
開源世界中涌現出不少 OXMapping 框架,包括 XStream 、 Digester 、 Castor 等。 XStream 和 Digester 把映射的過程在代碼中完成,而 Castor 則須要寫一個和 Hibernate 中 cfg.xml 相似的映射配置文件。
與 Digester 比起來, XStream 的主要優勢就是更加小巧,使用也更加方便,不過目前使用 Digester 是「開源名牌」 Apache 下的子項目,網上能夠參考的資料也比 XStream 多,好在 XStream 比較簡潔,因此並不會對 XStream 形成太大影響。框架
============================================================================
1、利用dom4j解析xml
認識一下它的接口:dom
Attribute
Attribute定義了XML的屬性工具
Branch
Branch爲可以包含子節點的節點如XML元素(Element)和文檔(Docuemnts)定義了一個公共的行爲網站
CDATA
CDATA 定義了XML CDATA 區域編碼
CharacterData
CharacterData是一個標識藉口,標識基於字符的節點。如CDATA,Comment, Text.
Comment
Comment 定義了XML註釋的行爲
Document
定義了XML文檔
DocumentType
DocumentType 定義XML DOCTYPE聲明
Element
Element定義XML 元素
ElementHandler
ElementHandler定義了 Element 對象的處理器
ElementPath
被 ElementHandler 使用,用於取得當前正在處理的路徑層次信息
Entity
Entity定義 XML entity
Node
Node爲全部的dom4j中XML節點定義了多態行爲
NodeFilter
NodeFilter 定義了在dom4j節點中產生的一個濾鏡或謂詞的行爲(predicate)
ProcessingInstruction
ProcessingInstruction 定義 XML 處理指令.
Text
Text 定義XML 文本節點.
Visitor
Visitor 用於實現Visitor模式.
XPath
XPath 在分析一個字符串後會提供一個XPath 表達式
看名字大體就知道它們的涵義如何了。
================================================================
具體實現技術:
1. 讀取並解析XML文檔:
讀寫XML文檔主要依賴於org.dom4j.io包,其中提供DOMReader和SAXReader兩類不一樣方式,而調用方式是同樣的。這就是依靠接口的好處。
從文件讀取XML,輸入文件名,返回XML文檔
public Document read(String fileName) throws MalformedURLException, DocumentException {
SAXReader reader = new SAXReader();
Document document = reader.read(new File(fileName));
return document;
}
其中,reader的read方法是重載的,能夠從InputStream, File, Url等多種不一樣的源來讀取。獲得的Document對象就帶表了整個XML。
根據本人本身的經驗,讀取的字符編碼是按照XML文件頭定義的編碼來轉換。若是遇到亂碼問題,注意要把各處的編碼名稱保持一致便可。
2. 取得Root節點
讀取後的第二步,就是獲得Root節點。熟悉XML的人都知道,一切XML分析都是從Root元素開始的。
public Element getRootElement(Document doc){
return doc.getRootElement();
}
3. 遍歷XML樹(暫時小結4種方法)
DOM4J提供至少3種遍歷節點的方法:
1) 迭代全部子節點
for ( Iterator i = root.elementIterator(); i.hasNext(); ) {
Element element = (Element) i.next();
}
迭代名稱爲foo的節點,這招很牛能夠準肯定位指定類型的節點
for ( Iterator i = root.elementIterator(foo); i.hasNext();) {
Element foo = (Element) i.next();
}
迭代屬性
for ( Iterator i = root.attributeIterator(); i.hasNext(); ) {
Attribute attribute = (Attribute) i.next();
}
2)遞歸
遞歸也能夠採用Iterator做爲枚舉手段,但文檔中提供了另外的作法
public void treeWalk() {
treeWalk(getRootElement());
}
public void treeWalk(Element element) {
for (int i = 0, size = element.nodeCount(); i < size; i++) {
Node node = element.node(i);
if (node instanceof Element) {
treeWalk((Element) node);
} else { // do something....
}
}
}
3) Visitor模式(訪問者模式),很方變!
最使人興奮的是DOM4J對Visitor的支持,這樣能夠大大縮減代碼量,而且清楚易懂。瞭解設計模式的人都知道,Visitor是GOF設計模式之一。其主要原理就是兩種類互相保有對方的引用,而且一種做爲Visitor去訪問許多Visitable。咱們來看DOM4J中的Visitor模式(快速文檔中沒有提供)
只須要自定一個類實現Visitor接口便可。+
public class MyVisitor extends VisitorSupport {
public void visit(Element element){
System.out.println(element.getName());
}
public void visit(Attribute attr){
System.out.println(attr.getName());
}
}
調用: root.accept(new MyVisitor())
Visitor接口提供多種Visit()的重載,根據XML不一樣的對象,將採用不一樣的方式來訪問。上面是給出的Element和Attribute的簡單實現,通常比較經常使用的就是這兩個。VisitorSupport是DOM4J提供的默認適配器,Visitor接口的Default Adapter模式,這個模式給出了各類visit(*)的空實現,以便簡化代碼。
注意,這個Visitor是自動遍歷全部子節點的。若是是root.accept(MyVisitor),將遍歷子節點。我第一次用的時候,認爲是須要本身遍歷,便在遞歸中調用Visitor,結果可想而知。
4). XPath支持,我比較喜歡用這個方法解析xml,目的性強,靈活!
DOM4J對XPath有良好的支持,如訪問一個節點,可直接用XPath選擇。
public void bar(Document document) {
注意:括號內路徑的寫法
List list = document.selectNodes( //foo/bar );
for(int i=0;i<list.size();i++){
Element ee=(Element)list.get(i);
String name=ee.getName();
String value=ee.getText();
}
Node node = document.selectSingleNode(//foo/bar/author);
//Element elem = (Element)doc.selectSingleNode("//subA");
String name = node.valueOf( @name );
}
例如,若是你想查找XHTML文檔中全部的超連接,下面的代碼能夠實現:
public void findLinks(Document document) throws DocumentException {
List list = document.selectNodes( //a/@href );
for (Iterator iter = list.iterator(); iter.hasNext(); ) {
Attribute attribute = (Attribute) iter.next();
String url = attribute.getValue();
}
}
5. 字符串與XML的轉換
有時候常常要用到字符串轉換爲XML或反之,
XML轉字符串
Document document = ...;
String text = document.asXML();
字符串轉XML
String text = 「<person> <name>James</name> </person>「;
Document document = DocumentHelper.parseText(text);
6 、用XSLT轉換XML
public Document styleDocument( Document document, String stylesheet ) throws Exception {
TransformerFactory factory = TransformerFactory.newInstance();
Transformer transformer = factory.newTransformer(new StreamSource( stylesheet )
);
// now lets style the given document
DocumentSource source = new DocumentSource( document );
DocumentResult result = new DocumentResult();
transformer.transform( source, result );
// return the transformed document
Document transformedDoc = result.getDocument();
return transformedDoc;
}
7. 建立XML
通常建立XML是寫文件前的工做,這就像StringBuffer同樣容易。
public Document createDocument() {
Document document = DocumentHelper.createDocument();
Element root = document.addElement(root);
Element author1 =
root
.addElement(author)
.addAttribute(name, James)
.addAttribute(location, UK)
.addText(James Strachan);
Element author2 =
root
.addElement(author)
.addAttribute(name, Bob)
.addAttribute(location, US)
.addText(Bob McWhirter);
return document;
}
8. 文件輸出
一個簡單的輸出方法是將一個Document或任何的Node經過write方法輸出
FileWriter out = new FileWriter( foo.xml );
document.write(out);
若是你想改變輸出的格式,好比美化輸出或縮減格式,能夠用XMLWriter類
public void write(Document document) throws IOException {
XMLWriter writer = new XMLWriter(
new FileWriter( output.xml )
);
writer.write( document );
writer.close();
// 美化格式
OutputFormat format = OutputFormat.createPrettyPrint();
writer = new XMLWriter( System.out, format );
writer.write( document );
// 縮減格式
format = OutputFormat.createCompactFormat();
writer = new XMLWriter( System.out, format );
writer.write( document );
}
這裏有兩點須要注意的:
( 1 ) OutputFormat format = OutputFormat.createPrettyPrint()
XML 一般是須要人閱讀的, Dom4j 默認的生成格式是緊縮格式的,這樣能夠減小空間佔用,可是帶來的缺點就是文件格式很是難看,所以咱們採用鎖緊格式進行輸出。
( 2 ) format.setEncoding("GB2312")
Dom4j 默認的編碼格式是「 UTF-8 」,這在輸出中文字符的時候會有問題,所以咱們改爲「 GB2312 」格式。
這裏使用了 Dom4j 提供的工具類 DocumentHelper 提供的 createElement 方法來建立一個節點,這個工具類還有 public static CDATA createCDATA(String text) 、 public static Comment createComment(String text) 、 public static Entity createEntity(String name, String text) 等方法能夠幫助咱們更快的建立節點。 DocumentHelper 還提供了 parseText 方法,能夠直接將字符串解析成 Documen 對象。九、修改節點、刪除節點(略,寫的太累拉)Element有幾個重要的方法: addComment:添加註釋 addAttribute:添加屬性 addElement:添加子元素 addText:添加節點值 setText:修改節點值 setvalue:修改節點值 remove:刪除節點值