与利用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秒
本文介绍DOM4J解析XML的技术细节,包括DOM4J API的使用方法、XML文件的创建、更新及读取操作,并提供了详细的代码示例。
2889

被折叠的 条评论
为什么被折叠?



