java部分

DOM4J

与利用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 获取注释

环境:

Dom4j-1.6.1

Dom4j解析需要XML需要的最小类库为:

dom4j-1.6.1.jar

jaxen-1.1-beta-6.jar

目标:

解析一个xml,输出所有的属性和元素值。

测试代码:

XML文件:

zhangsan

32

home add

com add

lisi

22

home add

com add

com add

解析代码:

packagecom.topsoft.test;importorg.dom4j.io.SAXReader;importorg.dom4j.Document;importorg.dom4j.DocumentException;importorg.dom4j.Element;importorg.dom4j.Node;importjava.util.Iterator;importjava.util.List;importjava.io.InputStream;/*** Created by IntelliJ IDEA.

* User: leizhimin

* Date: 2008-3-26 15:53:51

* Note: Dom4j遍历解析XML测试*/

public classTestDom4j {/*** 获取指定xml文档的Document对象,xml文件必须在classpath中可以找到

*

*@paramxmlFilePath xml文件路径

*@returnDocument对象*/

public staticDocument parse2Document(String xmlFilePath) {

SAXReader reader= newSAXReader();

Document document= null;try{

InputStream in= TestDom4j.class.getResourceAsStream(xmlFilePath);

document=reader.read(in);

}catch(DocumentException e) {

System.out.println(e.getMessage());

System.out.println("读取classpath下xmlFileName文件发生异常,请检查CLASSPATH和文件名是否存在!");

e.printStackTrace();

}returndocument;

}public static voidtestParseXMLData(String xmlFileName) {//产生一个解析器对象

SAXReader reader = newSAXReader();//将xml文档转换为Document的对象

Document document =parse2Document(xmlFileName);//获取文档的根元素

Element root =document.getRootElement();//定义个保存输出xml数据的缓冲字符串对象

StringBuffer sb = newStringBuffer();

sb.append("通过Dom4j解析XML,并输出数据:\n");

sb.append(xmlFileName+ "\n");

sb.append("----------------遍历start----------------\n");//遍历当前元素(在此是根元素)的子元素

for (Iterator i_pe =root.elementIterator(); i_pe.hasNext();) {

Element e_pe=(Element) i_pe.next();//获取当前元素的名字

String person =e_pe.getName();//获取当前元素的id和sex属性的值并分别赋给id,sex变量

String id = e_pe.attributeValue("id");

String sex= e_pe.attributeValue("sex");

String name= e_pe.element("name").getText();

String age= e_pe.element("age").getText();//将数据存放到缓冲区字符串对象中

sb.append(person + ":\n");

sb.append("\tid=" + id + " sex=" + sex + "\n");

sb.append("\t" + "name=" + name + " age=" + age + "\n");//获取当前元素e_pe(在此是person元素)下的子元素adds

Element e_adds = e_pe.element("adds");

sb.append("\t" + e_adds.getName() + "\n");//遍历当前元素e_adds(在此是adds元素)的子元素

for (Iterator i_adds =e_adds.elementIterator(); i_adds.hasNext();) {

Element e_add=(Element) i_adds.next();

String code= e_add.attributeValue("code");

String add=e_add.getTextTrim();

sb.append("\t\t" + e_add.getName() + ":" + " code=" + code + " value=\"" + add + "\"\n");

}

sb.append("\n");

}

sb.append("-----------------遍历end-----------------\n");

System.out.println(sb.toString());

System.out.println("---------通过XPath获取一个元素----------");

Node node1= document.selectSingleNode("/doc/person");

System.out.println("输出节点:" +

"\t"+node1.asXML());

Node node2= document.selectSingleNode("/doc/person/@sex");

System.out.println("输出节点:" +

"\t"+node2.asXML());

Node node3= document.selectSingleNode("/doc/person[name=\"zhangsan\"]/age");

System.out.println("输出节点:" +

"\t"+node3.asXML());

System.out.println("\n---------XPath获取List节点测试------------");

List list= document.selectNodes("/doc/person[name=\"zhangsan\"]/adds/add");for(Iterator it=list.iterator();it.hasNext();){

Node nodex=(Node)it.next();

System.out.println(nodex.asXML());

}

System.out.println("\n---------通过ID获取元素的测试----------");

System.out.println("陷阱:通过ID获取,元素ID属性名必须为“大写ID”,小写的“id”会认为是普通属性!");

String id22= document.elementByID("22").asXML();

String id23= document.elementByID("23").asXML();

String id24= null;if (document.elementByID("24") != null) {

id24= document.elementByID("24").asXML();

}else{

id24= "null";

}

System.out.println("id22= " +id22);

System.out.println("id23= " +id23);

System.out.println("id24= " +id24);

}public static voidmain(String args[]) {

testParseXMLData("/person.xml");

}

}

运行结果:

通过Dom4j解析XML,并输出数据:

/person.xml

----------------遍历start----------------

person:

id=1 sex=m

name=zhangsan age=32

adds

add: code=home value="home add"

add: code=com value="com add"

person:

id=2 sex=w

name=lisi age=22

adds

add: code=home value="home add"

add: code=com value="com add"

add: code=com value="com add"

-----------------遍历end-----------------

---------通过XPath获取一个元素----------

输出节点:

zhangsan

32

home add

com add

输出节点: sex="m"

输出节点:32---------XPath获取List节点测试------------home add

com add---------通过ID获取元素的测试----------

陷阱:通过ID获取,元素ID属性名必须为“大写ID”,小写的“id”会认为是普通属性!

id22=home addid23=com addid24= null

Process finished with exit code 0

实例一:

//先加入dom4j.jar包

importjava.util.HashMap;importjava.util.Iterator;importjava.util.Map;importorg.dom4j.Document;importorg.dom4j.DocumentException;importorg.dom4j.DocumentHelper;importorg.dom4j.Element;/*** @Title: TestDom4j.java

* @Package

* @Description: 解析xml字符串

*@author无处不在

* @date 2012-11-20 下午05:14:05

*@versionV1.0*/

public classTestDom4j {public voidreadStringXml(String xml) {

Document doc= null;try{//读取并解析XML文档//SAXReader就是一个管道,用一个流的方式,把xml文件读出来//

//SAXReader reader = new SAXReader();//User.hbm.xml表示你要解析的xml文档//Document document = reader.read(new File("User.hbm.xml"));//下面的是通过解析xml字符串的

doc = DocumentHelper.parseText(xml); //将字符串转为XML

Element rootElt= doc.getRootElement(); //获取根节点

System.out.println("根节点:" + rootElt.getName()); //拿到根节点的名称

Iterator iter= rootElt.elementIterator("head"); //获取根节点下的子节点head//遍历head节点

while(iter.hasNext()) {

Element recordEle=(Element) iter.next();

String title= recordEle.elementTextTrim("title"); //拿到head节点下的子节点title值

System.out.println("title:" +title);

Iterator iters= recordEle.elementIterator("script"); //获取子节点head下的子节点script//遍历Header节点下的Response节点

while(iters.hasNext()) {

Element itemEle=(Element) iters.next();

String username= itemEle.elementTextTrim("username"); //拿到head下的子节点script下的字节点username的值

String password = itemEle.elementTextTrim("password");

System.out.println("username:" +username);

System.out.println("password:" +password);

}

}

Iterator iterss= rootElt.elementIterator("body"); ///获取根节点下的子节点body//遍历body节点

while(iterss.hasNext()) {

Element recordEless=(Element) iterss.next();

String result= recordEless.elementTextTrim("result"); //拿到body节点下的子节点result值

System.out.println("result:" +result);

Iterator itersElIterator= recordEless.elementIterator("form"); //获取子节点body下的子节点form//遍历Header节点下的Response节点

while(itersElIterator.hasNext()) {

Element itemEle=(Element) itersElIterator.next();

String banlce= itemEle.elementTextTrim("banlce"); //拿到body下的子节点form下的字节点banlce的值

String subID = itemEle.elementTextTrim("subID");

System.out.println("banlce:" +banlce);

System.out.println("subID:" +subID);

}

}

}catch(DocumentException e) {

e.printStackTrace();

}catch(Exception e) {

e.printStackTrace();

}

}/*** @description 将xml字符串转换成map

*@paramxml

*@returnMap*/

public staticMap readStringXmlOut(String xml) {

Map map= newHashMap();

Document doc= null;try{//将字符串转为XML

doc =DocumentHelper.parseText(xml);//获取根节点

Element rootElt =doc.getRootElement();//拿到根节点的名称

System.out.println("根节点:" +rootElt.getName());//获取根节点下的子节点head

Iterator iter = rootElt.elementIterator("head");//遍历head节点

while(iter.hasNext()) {

Element recordEle=(Element) iter.next();//拿到head节点下的子节点title值

String title = recordEle.elementTextTrim("title");

System.out.println("title:" +title);

map.put("title", title);//获取子节点head下的子节点script

Iterator iters = recordEle.elementIterator("script");//遍历Header节点下的Response节点

while(iters.hasNext()) {

Element itemEle=(Element) iters.next();//拿到head下的子节点script下的字节点username的值

String username = itemEle.elementTextTrim("username");

String password= itemEle.elementTextTrim("password");

System.out.println("username:" +username);

System.out.println("password:" +password);

map.put("username", username);

map.put("password", password);

}

}//获取根节点下的子节点body

Iterator iterss = rootElt.elementIterator("body");//遍历body节点

while(iterss.hasNext()) {

Element recordEless=(Element) iterss.next();//拿到body节点下的子节点result值

String result = recordEless.elementTextTrim("result");

System.out.println("result:" +result);//获取子节点body下的子节点form

Iterator itersElIterator = recordEless.elementIterator("form");//遍历Header节点下的Response节点

while(itersElIterator.hasNext()) {

Element itemEle=(Element) itersElIterator.next();//拿到body下的子节点form下的字节点banlce的值

String banlce = itemEle.elementTextTrim("banlce");

String subID= itemEle.elementTextTrim("subID");

System.out.println("banlce:" +banlce);

System.out.println("subID:" +subID);

map.put("result", result);

map.put("banlce", banlce);

map.put("subID", subID);

}

}

}catch(DocumentException e) {

e.printStackTrace();

}catch(Exception e) {

e.printStackTrace();

}returnmap;

}public static voidmain(String[] args) {//下面是需要解析的xml字符串例子

String xmlString = "" + "

" + "dom4j解析一个例子"

+ "

+ "123456" + "" + ""

+ "

" + "0" + ""

+ "1000" + "36242519880716"

+ "

" + "" + "";/** Test2 test = new Test2(); test.readStringXml(xmlString);*/Map map=readStringXmlOut(xmlString);

Iterator iters=map.keySet().iterator();while(iters.hasNext()) {

String key= iters.next().toString(); //拿到键

String val = map.get(key).toString(); //拿到值

System.out.println(key + "=" +val);

}

}

}

实例二:

/*** 解析包含有DB连接信息的XML文件

* 格式必须符合如下规范:

* 1. 最多三级,每级的node名称自定义;

* 2. 二级节点支持节点属性,属性将被视作子节点;

* 3. CDATA必须包含在节点中,不能单独出现。

*

* 示例1——三级显示:

*

*

* DBTest

*

*

*

*

* org.gjt.mm.mysql.Driver

* test

* test2012

* 10

* 10

* 2

* 10

* SELECT 1+1

*

*

*

* 示例2——节点属性:

*

*

*

Everyday Italian

* Giada De Laurentiis

* 2005

* 30.00

*

*

*

*

*

*@paramconfigFile

*@return*@throwsException*/

public static List> parseDBXML(String configFile) throwsException {

List> dbConnections = new ArrayList>();

InputStream is= Parser.class.getResourceAsStream(configFile);

SAXReader saxReader= newSAXReader();

Document document=saxReader.read(is);

Element connections=document.getRootElement();

Iterator rootIter =connections.elementIterator();while(rootIter.hasNext()) {

Element connection=rootIter.next();

Iterator childIter =connection.elementIterator();

Map connectionInfo = new HashMap();

List attributes =connection.attributes();for (int i = 0; i < attributes.size(); ++i) { //添加节点属性

connectionInfo.put(attributes.get(i).getName(), attributes.get(i).getValue());

}while (childIter.hasNext()) { //添加子节点

Element attr =childIter.next();

connectionInfo.put(attr.getName().trim(), attr.getText().trim());

}

dbConnections.add(connectionInfo);

}returndbConnections;

}

一、dom4j介绍

dom4j是一个Java的XML API,类似于jdom,用来读写XML文件的。dom4j是一个非常非常优秀的Java XML API,具有性能优异、功能强大和极端易用使用的特点,同时它也是一个开放源代码的软件,可以在SourceForge上找到它。在IBM developerWorks上面可以找到一篇文章,对主流的Java XML API进行的性能、功能和易用性的评测,dom4j无论在那个方面都是非常出色的。如今你可以看到越来越多的Java软件都在使用dom4j来读写XML,特别值得一提的是连Sun的JAXM也在用dom4j。这是必须使用的jar包, Hibernate用它来读写配置文件。

dom4j主要接口都在org.dom4j这个包里定义:

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 表达式

看名字大致就知道它们的涵义如何了。要想弄懂这套接口,关键的是要明白接口的继承关系:

interface java.lang.Cloneable

interface org.dom4j.Node

interface org.dom4j.Attribute

interface org.dom4j.Branch

interface org.dom4j.Document

interface org.dom4j.Element

interface org.dom4j.CharacterData

interface org.dom4j.CDATA

interface org.dom4j.Comment

interface org.dom4j.Text

interface org.dom4j.DocumentType

interface org.dom4j.Entity

interface org.dom4j.ProcessingInstruction

一目了然,很多事情都清楚了。大部分都是由Node继承来的。知道这些关系,将来写程序就不会出现ClassCastException了。

二、使用dom4j创建xml文档

Document document = DocumentHelper.createDocument();

通过这句定义一个XML文档对象。

Element root = document.addElement("根节点名称");

通过这句定义一个XML元素,这里添加的是根节点。

Element有几个重要的方法:

addComment : 添加注释

addAttribute : 添加属性

addElement : 添加子元素

最后通过XMLWriter生成物理文件,默认生成的XML文件排版格式比较乱,可以通过OutputFormat类格式化输出,默认采用createCompactFormat()显示比较紧凑,最好使用createPrettyPrint()。

实例代码

public static void main(String[] args) {

// 创建文档。

Document document = DocumentHelper.createDocument();

// 设置文档DocType,这里为了举例,添加hibernate的DocType

document.addDocType("hibernate-configuration",

"-//Hibernate/Hibernate Configuration DTD 3.0//EN", "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd");

// 文档增加节点,即根节点,一个文档只能有一个根节点,多加出错

Element root = document.addElement("skills");

// 添加注释

root.addComment("第一个技能");

// 根节点下添加节点

Element first = root.addElement("skill");

// 节点添加属性

first.addAttribute("name", "独孤九剑");

// 节点下添加节点

Element info = first.addElement("info");

// 节点设置内容数据

info.setText("为独孤求败所创,变化万千,凌厉无比。其传人主要有风清扬、令狐冲。");

// 同理增加其他节点,内容,属性等

Element second = root.addElement("skill");

second.addAttribute("name", "葵花宝典");

Element info2 = second.addElement("info");

info2.setText("宦官所创,博大精深,而且凶险至极。练宝典功夫时,首先要自宫净身。");

// 创建节点

Element third = DocumentHelper.createElement_x("skill");

// 将节点加入到根节点中

root.add(third);

// 创建属性,第一个参数指定了拥有者,也可以为null,指定拥有者

Attribute name = DocumentHelper.createAttribute(third, "name", "北冥神功");

// 将属性加入到节点上

third.add(name);

// 创建子节点并加入到节点中

Element info3 = DocumentHelper.createElement_x("info");

info3.setText("逍遥派的顶级内功之一,能吸人内力转化为自己所有,威力无穷。");

third.add(info3);

try {

// 创建格式化类

OutputFormat format = OutputFormat.createPrettyPrint();

// 设置编码格式,默认UTF-8

format.setEncoding("UTF-8");

// 创建输出流,此处要使用Writer,需要指定输入编码格式,使用OutputStream则不用

FileOutputStream fos = new FileOutputStream("d:/skills.xml");

// 创建xml输出流

XMLWriter writer = new XMLWriter(fos, format);

// 生成xml文件

writer.write(document);

writer.close();

} catch (Exception e) {

e.printStackTrace();

}

}

生成XML文件内容

为独孤求败所创,变化万千,凌厉无比。其传人主要有风清扬、令狐冲。

宦官所创,博大精深,而且凶险至极。练宝典功夫时,首先要自宫净身。

逍遥派的顶级内功之一,能吸人内力转化为自己所有,威力无穷。

三、使用dom4j解析xml文件

1. 构建dom4j树

org.dom4j.io提供了两个类:SAXReader和DOMReader,DOMReader只能一个现有的w3c DOM树构建dom4j树,即只能从一个org.w3c.dom.Document中构建org.dom4j.Document树,而SAXReader则使用SAX解析器,从不同的输入源构建dom4j树,如可以从xml文件中读取并构建dom4j树。

实例代码:使用SAXReader解析

SAXReader reader = new SAXReader();

Document document = reader.read(new File("d:/skills.xml"));

实例代码:使用DOMReader解析

DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();

DocumentBuilder db = dbf.newDocumentBuilder();

File file = new File("d:/skills.xml");

org.w3c.dom.Document domDocument = db.parse(file);

DOMReader reader = new DOMReader();

org.dom4j.Document document = reader.read(domDocument);

2. 获取节点

获得dom4j树之后,可以根据dom4j树获取节点。首先获取根节点,然后根据根节点获取其子节点。

实例代码:访问根节点

Element root = document.getRootElement();

实例代码:访问所有子节点

List skills = root.elements();

for (Iterator> it = skills.iterator(); it.hasNext();) {

Element e = (Element) it.next();

//TODO

}

实例代码:访问指定名称的节点,如访问名称为“skill”的全部节点

List skills = root.elements("skill");

for (Iterator> it = skills.iterator(); it.hasNext();) {

Element e = (Element) it.next();

//TODO

}

实例代码:访问指定名称的第一个节点

Element skill = root.element("skill");

实例代码:迭代某个元素的所有子元素,如迭代root

for(Iterator it = root.elementIterator();it.hasNext();){

Element e = it.next();

//TODO

}

3. 获取属性

获取节点后,可以根据节点获取属性,获得方式与获取节点类似。

实例代码:获取指定名称的元素

Element skill = root.element("skill");

Attribute attr1 = skill.attribute("name");

实例代码:按照属性顺序获取属性,

Element skill = root.element("skill");

Attribute attr2 = skill.attribute(0);

实例代码:获取某节点下全部属性1

Element skill = root.element("skill");

List list = skill.attributes();

for (Iterator it = list.iterator(); it.hasNext();) {

Attribute attr = it.next();

// TODO

}

实例代码:获取某节点下全部属性2

Element skill = root.element("skill");

for (Iterator it = skill.attributeIterator(); it.hasNext();) {

Attribute attr = it.next();

// TODO

}

4. 使用XPath获取节点和属性

Dom4j 中集成了对XPath的支持。在选择节点时,可以直接使用XPath 表达式。这种方式更加方便,简洁,官方文档中推荐使用该种方式。

实例代码:要选择所有的元素的name属性

List list = document.selectNodes("//skills/skill/@name");

for (Iterator it = list.iterator(); it.hasNext();) {

Attribute attr = (Attribute) it.next();

//TODO

}

注意:为了能够编译执行上述使用XPath表达式的代码,需要配置dom4j 安装包中自带的jaxen包,你也可以从http://sourceforge.net/products/jaxen/上下载jaxen。jaxen是一个用java开发的XPath引擎,用于配合各种基于XML的对象模型,如DOM,dom4j和JDOM。在dom4-1.6.1 目录下,有一个lib 子目录,其中有个jaxen-1.1-beta-6.jar文件,需要在classpath环境变量中配置该文件的全路径名。

四、使用dom4j修改xml文件

修改xml文件,需要先获取dom4j树(即Document),通常欲修改节点需要先获得该节点或其父节点,欲修改属性,需要先获得该属性所在的节点和该属性。

增加操作:参照前文。

删除操作:

实例代码:删除某节点

Element root = document.getRootElement();

Element skill = root.element("skill");

root.remove(skill);

实例代码:删除指定名称的属性

Element skill = root.element("skill");

skill.remove(skill.attribute("name"));

修改操作:

实例代码:修改节点名称和节点值

Element skill = root.element("skill");

skill.setName("new_skill");

skill.setText("你好");

实例代码:修改属性值

Attribute attr = skill.attribute("name");

attr.setText("newName");

属性名称无法修改,欲修改属性名称,可以先删除旧属性,再增加新属性

五、常用方法

1.Element元素API

Method Comment

getQName() 元素的QName对象

getNamespace() 元素所属的Namespace对象

getNamespacePrefix() 元素所属的Namespace对象的prefix

getNamespaceURI() 元素所属的Namespace对象的URI

getName() 元素的local name

getQualifiedName() 元素的qualified name

getText() 元素所含有的text内容,如果内容为空则返回一个空字符串而不是null

getTextTrim() 元素所含有的text内容,其中连续的空格被转化为单个空格,该方法不会返回null

attributeIterator() 元素属性的iterator,其中每个元素都是Attribute对象

attributeValue() 元素的某个指定属性所含的值

elementIterator() 元素的子元素的iterator,其中每个元素都是Element对象

element() 元素的某个指定(qualified name或者local name)的子元素

elementText() 元素的某个指定(qualified name或者local name)的子元素中的text信息

getParent 元素的父元素

getPath() 元素的XPath表达式,其中父元素的qualified name和子元素的qualified name之间使用"/"分隔

isTextOnly() 是否该元素只含有text或是空元素

isRootElement() 是否该元素是XML树的根节点

2. Attribute属性API

Method Comment

getQName() 属性的QName对象

getNamespace() 属性所属的Namespace对象

getNamespacePrefix() 属性所属的Namespace对象的prefix

getNamespaceURI() 属性所属的Namespace对象的URI

getName() 属性的local name

getQualifiedName() 属性的qualified name

getValue() 属性的值

2. 字符串转化

实例代码:把节点,属性,文档等转化成字符串,使用asXML()方法。

String docXmlText = document.asXML();

String rootXmlText = root.asXML();

实例代码:把字符串转换为文档,注意引号需要转义

String skillString = "神龙摆尾";

Document d = DocumentHelper.parseText(skillString);

3. 命名空间(Namespace)操作

dom4j的名称空间信息api常用的方法有8个。

dom4j在Element和Attribute 接口中定义了获取名称空间信息的方法,这些方法和JDOM中的方法相同。如下所示:

public java.lang.String getNamespacePrefix()该方法返回元素(属性)的名称空间前缀

public java.lang.String getNamespaceURI()该方法返回元素(属性)的名称空间

URIpublic java.lang.String getName()该方法返回元素(属性)的本地名

public java.lang.String getQualifiedName()该方法返回元素(属性)的限定名

public Namespace getNamespace()该方法返回元素本身的名称空间

public java.util.List additionalNamespaces()返回某元素上附加的名称空间声明列表,列表中的每一个对象都是Namespace类型。

这个类的方法提供了两个方法分别获得名称空间前缀和本地名。如下:

public java.lang.String getPrefix()该方法返回名称空间前缀。

public java.lang.String getURI()该方法返回名称空间的URI。

六、Qname介绍

Qname在使用dom4j的时候,经常见到,一般自己解析的xml很少使用这种复杂格式。

1. 来历:qname是qualified name的简写

2. 构成:由名字空间(namespace)前缀(prefix)以及冒号(:),还有一个元素名称构成

3. 举例:

xmlns="http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"

version="1.0">


xsl是名字空间前缀,template是元素名称,xsl:template 就是一个qname。

4.总结:qname无非是有着特定格式的xml元素,其作用主要是增加了名字空间,比如有同样的元素名称,而名字空间不同的情况。

七、Visitor模式

dom4j对visitor的支持可以大大缩减代码量,并且清楚易懂。这个模式很有用、很实用!

自己的类需要继承VisitorSupport,由于VisitorSupport使用适配器模式,可以覆写需要的方法,不需要的方法VisitorSupport提供了空实现。

实例代码:MyVisitor,这里将所有可以覆写的visit方法都显示了,可以根据需要覆写

packagepiaohan.util.xml;importorg.dom4j.Attribute;importorg.dom4j.CDATA;importorg.dom4j.Comment;importorg.dom4j.Document;importorg.dom4j.DocumentType;importorg.dom4j.Element;importorg.dom4j.Entity;importorg.dom4j.Namespace;importorg.dom4j.ProcessingInstruction;importorg.dom4j.Text;importorg.dom4j.VisitorSupport;public class MyVisitor extendsVisitorSupport {

@Overridepublic voidvisit(Attribute node) {super.visit(node);

}

@Overridepublic voidvisit(CDATA node) {super.visit(node);

}

@Overridepublic voidvisit(Comment node) {super.visit(node);

}

@Overridepublic voidvisit(Document document) {super.visit(document);

}

@Overridepublic voidvisit(DocumentType documentType) {super.visit(documentType);

}

@Overridepublic voidvisit(Element node) {super.visit(node);

}

@Overridepublic voidvisit(Entity node) {super.visit(node);

}

@Overridepublic voidvisit(Namespace namespace) {super.visit(namespace);

}

@Overridepublic voidvisit(ProcessingInstruction node) {super.visit(node);

}

@Overridepublic voidvisit(Text node) {super.visit(node);

}

}

实例代码:例如,这里覆写了处理Element的方法

@Override

public void visit(Element node) {

System.out.println(node.asXML());

}

实例代码:程序中调用,

Element skill = root.element("skill");

MyVisitor visitor = new MyVisitor();

skill.accept(visitor);

这样,程序会从skill节点开始,遍历全部子节点和子属性,注释,CDATA等,即遍历skill节点内部的全部元素,由于我的MyVisitor只覆写了Element的处理方法,所以只处理所有的子节点。

程序结果:(xml内容见开篇例子)

为独孤求败所创,变化万千,凌厉无比。其传人主要有风清扬、令狐冲。

为独孤求败所创,变化万千,凌厉无比。其传人主要有风清扬、令狐冲。

清单 1. 示例 XML 文档(catalog.xml)

Java configuration with XML Schema

Marcello

Vitaletti

然后使用同一个解析器修改 catalog.xml,清单 2 是修改后的 XML 文档,catalog-modified.xml。

清单 2. 修改后的 XML 文档(catalog-modified.xml)

Create flexible and extensible XML schemas

Ayesha

Malik

与 W3C DOM API 相比,使用 dom4j 所包含的解析器的好处是 dom4j 拥有本地的 XPath 支持。DOM 解析器不支持使用 XPath 选择节点。

本文包括以下几个部分:

预先设置

创建文档

修改文档

预先设置

这个解析器可以从 http://dom4j.org 获取。通过设置使 dom4j-1.4/dom4j-full.jar 能够在 classpath 中访问,该文件中包括 dom4j 类、XPath 引擎以及 SAX 和 DOM 接口。如果已经使用了 JAXP 解析器中包含的 SAX 和 DOM 接口,向 classpath 中增加 dom4j-1.4/dom4j.jar 。 dom4j.jar 包括 dom4j 类和 XPath 引擎,但是不含 SAX 与 DOM 接口。

回页首

创建文档

本节讨论使用 dom4j API 创建 XML 文档的过程,并创建示例 XML 文档 catalog.xml。

使用 import 语句导入 dom4j API 类:

import org.dom4j.Document;

import org.dom4j.DocumentHelper;

import org.dom4j.Element;

使用 DocumentHelper 类创建一个文档实例。 DocumentHelper 是生成 XML 文档节点的 dom4j API 工厂类。

Document document = DocumentHelper.createDocument();

使用 addElement() 方法创建根元素 catalog 。 addElement() 用于向 XML 文档中增加元素。

Element catalogElement = document.addElement("catalog");

在 catalog 元素中使用 addComment() 方法添加注释“An XML catalog”。

catalogElement.addComment("An XML catalog");

在 catalog 元素中使用 addProcessingInstruction() 方法增加一个处理指令。

catalogElement.addProcessingInstruction("target","text");

在 catalog 元素中使用 addElement() 方法增加 journal 元素。

Element journalElement = catalogElement.addElement("journal");

使用 addAttribute() 方法向 journal 元素添加 title 和 publisher 属性。

journalElement.addAttribute("title", "XML Zone");

journalElement.addAttribute("publisher", "IBM developerWorks");

向 article 元素中添加 journal 元素。

Element articleElement=journalElement.addElement("article");

为 article 元素增加 level 和 date 属性。

articleElement.addAttribute("level", "Intermediate");

articleElement.addAttribute("date", "December-2001");

向 article 元素中增加 title 元素。

Element titleElement=articleElement.addElement("title");

使用 setText() 方法设置 article 元素的文本。

titleElement.setText("Java configuration with XML Schema");

在 article 元素中增加 author 元素。

Element authorElement=articleElement.addElement("author");

在 author 元素中增加 firstname 元素并设置该元素的文本。

Element firstNameElement=authorElement.addElement("firstname");

firstNameElement.setText("Marcello");

在 author 元素中增加 lastname 元素并设置该元素的文本。

Element lastNameElement=authorElement.addElement("lastname");

lastNameElement.setText("Vitaletti");

可以使用 addDocType() 方法添加文档类型说明。

document.addDocType("catalog", null,"file://c:/Dtds/catalog.dtd");

这样就向 XML 文档中增加文档类型说明:

如果文档要使用文档类型定义(DTD)文档验证则必须有 Doctype。

XML 声明 <?xml version="1.0" encoding="UTF-8"?> 自动添加到 XML 文档中。

清单 3 所示的例子程序 XmlDom4J.java 用于创建 XML 文档 catalog.xml。

清单 3. 生成 XML 文档 catalog.xml 的程序(XmlDom4J.java)

importorg.dom4j.Document;importorg.dom4j.DocumentHelper;importorg.dom4j.Element;importorg.dom4j.io.XMLWriter;import java.io.*;public classXmlDom4J{public voidgenerateDocument(){

Document document=DocumentHelper.createDocument();

Element catalogElement= document.addElement("catalog");

catalogElement.addComment("An XML Catalog");

catalogElement.addProcessingInstruction("target","text");

Element journalElement= catalogElement.addElement("journal");

journalElement.addAttribute("title", "XML Zone");

journalElement.addAttribute("publisher", "IBM developerWorks");

Element articleElement=journalElement.addElement("article");

articleElement.addAttribute("level", "Intermediate");

articleElement.addAttribute("date", "December-2001");

Element titleElement=articleElement.addElement("title");

titleElement.setText("Java configuration with XML Schema");

Element authorElement=articleElement.addElement("author");

Element firstNameElement=authorElement.addElement("firstname");

firstNameElement.setText("Marcello");

Element lastNameElement=authorElement.addElement("lastname");

lastNameElement.setText("Vitaletti");

document.addDocType("catalog",null,"file://c:/Dtds/catalog.dtd");try{

XMLWriter output= newXMLWriter(new FileWriter( new File("c:/catalog/catalog.xml") ));

output.write( document );

output.close();

}catch(IOException e){System.out.println(e.getMessage());}

}public static voidmain(String[] argv){

XmlDom4J dom4j=newXmlDom4J();

dom4j.generateDocument();

}}

这一节讨论了创建 XML 文档的过程,下一节将介绍使用 dom4j API 修改这里创建的 XML 文档。

回页首

修改文档

这一节说明如何使用 dom4j API 修改示例 XML 文档 catalog.xml。

使用 SAXReader 解析 XML 文档 catalog.xml:

SAXReader saxReader = new SAXReader();

Document document = saxReader.read(inputXml);

SAXReader 包含在 org.dom4j.io 包中。

inputXml 是从 c:/catalog/catalog.xml 创建的 java.io.File。使用 XPath 表达式从 article 元素中获得 level 节点列表。如果 level 属性值是“Intermediate”则改为“Introductory”。

List list = document.selectNodes("//article/@level");

Iterator iter=list.iterator();while(iter.hasNext()){

Attribute attribute=(Attribute)iter.next();if(attribute.getValue().equals("Intermediate"))

attribute.setValue("Introductory");

}

获取 article 元素列表,从 article 元素中的 title 元素得到一个迭代器,并修改 title 元素的文本。

list = document.selectNodes("//article");

iter=list.iterator();while(iter.hasNext()){

Element element=(Element)iter.next();

Iterator iterator=element.elementIterator("title");while(iterator.hasNext()){

Element titleElement=(Element)iterator.next();if(titleElement.getText().equals("Java configuration with XML Schema"))

titleElement.setText("Create flexible and extensible XML schema");

}}

通过和 title 元素类似的过程修改 author 元素。

清单 4 所示的示例程序 Dom4JParser.java 用于把 catalog.xml 文档修改成 catalog-modified.xml 文档。

清单 4. 用于修改 catalog.xml 的程序(Dom4Jparser.java)

importorg.dom4j.Document;importorg.dom4j.Element;importorg.dom4j.Attribute;importjava.util.List;importjava.util.Iterator;importorg.dom4j.io.XMLWriter;import java.io.*;importorg.dom4j.DocumentException;importorg.dom4j.io.SAXReader;public classDom4JParser{public voidmodifyDocument(File inputXml){try{

SAXReader saxReader= newSAXReader();

Document document=saxReader.read(inputXml);

List list= document.selectNodes("//article/@level");

Iterator iter=list.iterator();while(iter.hasNext()){

Attribute attribute=(Attribute)iter.next();if(attribute.getValue().equals("Intermediate"))

attribute.setValue("Introductory");

}

list= document.selectNodes("//article/@date");

iter=list.iterator();while(iter.hasNext()){

Attribute attribute=(Attribute)iter.next();if(attribute.getValue().equals("December-2001"))

attribute.setValue("October-2002");

}

list= document.selectNodes("//article");

iter=list.iterator();while(iter.hasNext()){

Element element=(Element)iter.next();

Iterator iterator=element.elementIterator("title");while(iterator.hasNext()){

Element titleElement=(Element)iterator.next();if(titleElement.getText().equals("Java configuration with XML

Schema"))

titleElement.setText("Create flexible and extensible XML schema");

}

}

list= document.selectNodes("//article/author");

iter=list.iterator();while(iter.hasNext()){

Element element=(Element)iter.next();

Iterator iterator=element.elementIterator("firstname");while(iterator.hasNext()){

Element firstNameElement=(Element)iterator.next();if(firstNameElement.getText().equals("Marcello"))

firstNameElement.setText("Ayesha");

}

}

list= document.selectNodes("//article/author");

iter=list.iterator();while(iter.hasNext()){

Element element=(Element)iter.next();

Iterator iterator=element.elementIterator("lastname");while(iterator.hasNext()){

Element lastNameElement=(Element)iterator.next();if(lastNameElement.getText().equals("Vitaletti"))

lastNameElement.setText("Malik");

}

}

XMLWriter output= newXMLWriter(new FileWriter( new File("c:/catalog/catalog-modified.xml") ));

output.write( document );

output.close();

}catch(DocumentException e)

{

System.out.println(e.getMessage());

}catch(IOException e){

System.out.println(e.getMessage());

}

}public static voidmain(String[] argv){

Dom4JParser dom4jParser=newDom4JParser();

dom4jParser.modifyDocument(new File("c:/catalog/catalog.xml"));

}

}

自已写的:

public voidparseXML(){

Document document=null;try{

document= new SAXReader().read(Thread.currentThread().getContextClassLoader().getResourceAsStream("book.xml"));

}catch(DocumentException e) {//TODO Auto-generated catch block

e.printStackTrace();

}

List books=document.selectNodes("//书/小说");for(Iterator iter =books.iterator(); iter.hasNext();){

Element element=(Element) iter.next();

System.out.println(element.getName());

System.out.println(element.getText());

System.out.println(element.attributeValue("name"));

}

}

java dom解析xml字符串_dom4j解析xml字符串实例相关推荐

  1. java dom 解析xml 例子,Java DOM解析XML的幾個例子

    Sample1: 1:新建XML文檔 books.xml,放到項目的根目錄下. xmlns="http://test.org/books"> Thinking in JAVA ...

  2. java dom xml 换行,dom4j解析xml文件_用DOM解析XML文件,怎么才能让解析出来的文本不用换行_dom解析xml文件...

    网友求助:dom4j解析xml文件_用DOM解析XML文件,怎么才能让解析出来的文本不用换行_dom解析xml文件 问题importjava.text.SimpleDateFormat; import ...

  3. java sax解析xml_在Java中使用DOM,SAX和StAX解析器解析XML

    java sax解析xml 我碰巧通读了有关Java中XML解析和构建API的章节. 我试用了样本XML上的其他解析器. 然后,我想在我的博客上分享它,这样我就可以得到该代码的参考以及任何阅读此代码的 ...

  4. 在Java中使用DOM,SAX和StAX解析器解析XML

    我碰巧通读了有关Java中的XML解析和构建API的章节. 我试用了样本XML上的其他解析器. 然后,我想在我的博客上分享它,这样我就可以参考该代码以及任何阅读此书的参考. 在本文中,我将在不同的解析 ...

  5. java w3c xml_org.w3c.dom(java dom)解析XML文档

    首先来了解点Java DOM 的 API: 1.解析器工厂类:DocumentBuilderFactory 创建的方法:DocumentBuilderFactory dbf = DocumentBui ...

  6. JAVA:DOM解析XML和修改XML

    JAVA:DOM解析XML和修改XML 一:工程结构: 二:类:XMLPARSER package com.demo.xml;import javax.xml.parsers.DocumentBuil ...

  7. java dom解析xml路径中文_Java如何基于DOM解析xml文件

    一.Java解析xml.解析xml四种方法.DOM.SAX.JDOM.DOM4j.XPath 此文针对其中的DOM方法具体展开介绍及代码分析 sax.dom是两种对xml文档进行解析的方法(没有具体实 ...

  8. java dom获取命名空间属性_Java DOM XML解析::获取元素属性值

    如何从元素中提取属性值.我的xml节点是这样写的 &LT nodename attribute ="value">我需要将其解压缩以将其与另一个字符串进行比较. 但由 ...

  9. java dom cdata_java – 通过DOM解析器从XML处理CDATA

    我以前从未处理过XML,所以我不确定如何在XML文件中处理CDATA.我迷失在节点,父节点,子节点,nList等中. 谁能告诉我这些代码片段的问题是什么? 我的getTagValue()方法适用于除& ...

最新文章

  1. Android开发之Buidler模式初探结合AlertDialog.Builder解说
  2. 二叉查找树的Java实现
  3. spring-Bean依赖注入-》普通数据类型
  4. faster_rcnn c++版本的 caffe 封装,动态库(2)
  5. uniapp连接php,thinkphp5 对接手机uni-app的unipush推送(个推)
  6. Python实现PLA(感知机)
  7. 【转】刨根究底字符编码之七——ANSI编码与代码页
  8. 查看oracle 锁定用户名,oracle用户名被锁定
  9. 伪代码 嵌套循环_大学开始,跟着别人的代码敲对自己编程提高有用吗?
  10. 浏览器设置(除了页面百分比之外,还有“字体大小”)
  11. 擦拭法 java 泛型_廖雪峰Java4反射与泛型-3范型-4擦拭法
  12. 机器学习- 吴恩达Andrew Ng Week9 知识总结 Anomaly Detection
  13. Optimus双显卡笔记本上用MediaCoder转换iPhone/iPod 4视频
  14. python机器视觉车牌识别_车牌识别系统中的机器视觉技术
  15. ubuntu18字符终端不支持中文问题(汉字菱形)
  16. Ubuntu 重置密码
  17. 【Linux】rm -rf 删除命令
  18. dismiss和remove_Android中dismissDialog(int id)和removeDialog(int id)两个接口有什么区别
  19. java流重定向如何分类,Java 文件流与标准流之间的重定向
  20. 设计模式(一)设计模式的分类与区别

热门文章

  1. 拉勾教育后台管理系统(SSM)(课程管理模块开发)【学习笔记】
  2. resultMap的用法
  3. 数据挖掘 第二篇:基于距离评估数据的相似性和相异性
  4. php 心跳检测,swoole 中的心跳检测
  5. 顺利通过软件评测师考试
  6. vi中如何实现批量替换?
  7. 关于decorator 的理解
  8. java开发mac pro_U1S1,这个提取人声/歌曲伴奏的小工具很好用 Neural Mix | Mac软件天堂...
  9. python之turtle画花
  10. 计算机毕业设计ssm力高灯饰线上交易平台4d59n系统+程序+源码+lw+远程部署