與利用DOM、SAX、JAXP機制來解析xml相比,DOM4J 表現更優秀,具有性能優異、功能強大和極端易用使用的特點,只要懂得DOM基本概念,就可以通過dom4j的api文檔來解析xml。dom4j是一套開源的api。實際項目中,往往選擇dom4j來作爲解析xml的利器。
先來看看dom4j中對應XML的DOM樹建立的繼承關係
針對於XML標準定義,對應於圖2-1列出的內容,dom4j提供了以下實現:
同時,dom4j的NodeType枚舉實現了XML規範中定義的node類型。如此可以在遍歷xml文檔的時候通過常量來判斷節點類型了。
常用API
class org.dom4j.io.SAXReader
- read 提供多種讀取xml文件的方式,返回一個Domcument對象
interface org.dom4j.Document
- iterator 使用此法獲取node
- getRootElement 獲取根節點
interface org.dom4j.Node
- getName 獲取node名字,例如獲取根節點名稱爲bookstore
- getNodeType 獲取node類型常量值,例如獲取到bookstore類型爲1——Element
- getNodeTypeName 獲取node類型名稱,例如獲取到的bookstore類型名稱爲Element
interface org.dom4j.Element
- attributes 返回該元素的屬性列表
- attributeValue 根據傳入的屬性名獲取屬性值
- elementIterator 返回包含子元素的迭代器
- elements 返回包含子元素的列表
interface org.dom4j.Attribute
- getName 獲取屬性名
- getValue 獲取屬性值
interface org.dom4j.Text
- getText 獲取Text節點值
interface org.dom4j.CDATA
- getText 獲取CDATA Section值
interface org.dom4j.Comment
- getText 獲取註釋
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
上文轉載處源於:http://www.cnblogs.com/macula/archive/2011/07/27/2118003.html
好了,廢話夠了,直接上代碼了!
/**
* 按照指定格式生成XML
* @param <font color=red>測試示例:</font>
* @param rootRow:code=1,nodeRow:name=outman&age=26&sex=男,nodeRow:name=xieshen&age=26&sex=男
* @param parameterStr 規範化XML創建參數
* @return
*/
public Boolean createXml(String parameterStr){
try{
//創建Document對象
Document document = DocumentHelper.createDocument();
//初始化子元素
Element element = null;
if(StringUtils.isNotBlank(parameterStr)){
String []commaSplits = parameterStr.split("\\,");
if(null!=commaSplits){
for(String commaSplit : commaSplits){
String []colonSplits = commaSplit.split("\\:");
if(null!=colonSplits){
if(colonSplits.length > 0){
if(ROOT_ROW.equals(colonSplits[0])){
//添加根節點
element = document.addElement(ROOT_ROW);
//給根節點添加備註
element.addComment("根節點:rootRow");
String []attrSplits = colonSplits[1].split("\\&");
if(null!=attrSplits){
if(attrSplits.length > 0){
for(String attrSplit : attrSplits){
String []attrAndValueSplits = attrSplit.split("\\=");
if(null!=attrAndValueSplits){
if(attrAndValueSplits.length>1){
//跟根節點添加屬性和值
element.addAttribute(attrAndValueSplits[0], attrAndValueSplits[1]);
}else{
this.systemErrorPrint();
}
}else{
this.systemErrorPrint();
}
}
}else{
this.systemErrorPrint();
}
}else{
this.systemErrorPrint();
}
}else if(NODE_ROW.equals(colonSplits[0])){
//在根節點的基礎上,添加子節點
Element element_ = element.addElement(NODE_ROW);
//給子節點添加備註
element_.addComment("子節點:nodeRow");
String []attrSplits = colonSplits[1].split("\\&");
if(null!=attrSplits){
if(attrSplits.length > 0){
for(String attrSplit : attrSplits){
String []attrAndValueSplits = attrSplit.split("\\=");
if(null!=attrAndValueSplits){
if(attrAndValueSplits.length>1){
//給子節點添加屬性和值
element_.addAttribute(attrAndValueSplits[0], attrAndValueSplits[1]);
}else{
this.systemErrorPrint();
}
}else{
this.systemErrorPrint();
}
}
element_.addText("這裏是子節點的內容");
}else{
this.systemErrorPrint();
}
}else{
this.systemErrorPrint();
}
}else{
this.systemErrorPrint();
}
}else{
this.systemErrorPrint();
}
}else{
this.systemErrorPrint();
}
}
}else{
this.systemErrorPrint();
}
}else{
this.systemErrorPrint();
}
//輸出文件到指定路徑
XMLWriter writer = new XMLWriter(new FileWriter(new File(STORE_PATH)));
writer.write(document);
writer.close();
System.out.println("1.創建指定規範XML成功,輸出地址:"+STORE_PATH);
return true;
}catch(Exception ex){
System.out.println("1.創建指定規範XML發生異常:"+ex.getMessage());
return false;
}
}
/**
* 修改指定內容,重新保存
* @return
*/
public Boolean updateXml(){
try{
SAXReader saxReader = new SAXReader();
Document document = saxReader.read(new File(STORE_PATH));
//這裏需要用到jaxen-1.1-beta-6包,如果不導入則會發生異常
@SuppressWarnings("unchecked")
List<Attribute> attrValues = document.selectNodes("/rootRow/nodeRow/@name");
if(null!=attrValues){
if(attrValues.size()>0){
Iterator<Attribute> interator = attrValues.iterator();
while(interator.hasNext()){
Attribute attribute = interator.next();
if("outman".equals(attribute.getValue())){
attribute.setValue("outman2013");
}
}
}else{
System.out.println("XML中沒有/rootRow/nodeRow/@name節點");
}
}else{
System.out.println("XML中沒有/rootRow/nodeRow/@name節點");
}
//輸出文件到指定路徑
XMLWriter writer = new XMLWriter(new FileWriter(new File(STORE_PATH)));
writer.write(document);
writer.close();
return true;
}catch(Exception ex){
System.out.println("2.修改指定規範XML發生異常:"+ex.getMessage());
return false;
}
}
/**
* 讀取指定路徑下XML內容
* @return
*/
@SuppressWarnings("unchecked")
public Boolean parseXml(){
try {
SAXReader saxReader = new SAXReader();
Document document = saxReader.read(new File(STORE_PATH));
Element element = document.getRootElement();
System.out.println("根節點:"+element.getName());
for(Iterator<Attribute> i = element.attributeIterator();i.hasNext();){
Attribute attribute = i.next();
System.out.println("根節點屬性:"+attribute.getName() +" ,根節點屬性值:"+ attribute.getValue());
}
for(Iterator<Element> i = element.elementIterator("nodeRow");i.hasNext();){
Element element_p = i.next();
System.out.println("子節點:"+element_p.getName());
for(Attribute attribute : (List<Attribute>)element_p.attributes()){
System.out.println("子節點屬性:"+attribute.getName() +" ,子節點屬性值:"+ attribute.getValue());
}
//這個地方的attributeIterator獲取的長度是4,遍歷的實際內容長度爲3,會報錯,換成attributes就可以了,這兩個方法有何區別?
// for(@SuppressWarnings("unchecked")Iterator<Attribute> i_ = element_p.attributeIterator();i.hasNext();){
// Attribute attribute = i_.next();
// System.out.println("子節點屬性:"+attribute.getName() +" ,子節點屬性值:"+ attribute.getValue());
// }
}
return true;
} catch (Exception ex) {
System.out.println("DOM4J讀取XML解析出現異常:"+ex.getMessage());
return false;
}
}
main方法中測試
public static void main(String[] args) {
long st1 = System.currentTimeMillis();
DomParseXML domParseXML = new DomParseXML();
//創建
//domParseXML.createXml("rootRow:code=1,nodeRow:name=outman&age=26&sex=男,nodeRow:name=xieshen&age=26&sex=男");
//修改
//domParseXML.updateXml();
//讀取
domParseXML.parseXml();
long st2 = System.currentTimeMillis();
System.out.println("執行秒數:" + ((st2-st1)/1000));
}
爲感興趣的朋友,可以點擊這裏:
http://pan.baidu.com/share/link?shareid=280030&uk=1443215090
dom4j api 使用簡介:
http://pan.baidu.com/share/link?shareid=280032&uk=1443215090
DOM、JDOM、SAX、DOM4J四種解析方式的比較
http://acjwht.blog.163.com/blog/static/33697435201161291653540
經測試,8MB的xml文件解析完畢用時11.2秒