Dom4j使用简介
2013-02-18 14:35
417 查看
1、DOM4J简介
DOM4J是dom4j.org出品的一个开源XML解析包。DOM4J应用于Java平台,采用了Java集合框架并完全支持DOM,SAX和JAXP。DOM4J使用起来非常简单。只要你了解基本的XML-DOM模型,就能使用。
Dom:把整个文档作为一个对象。
DOM4J最大的特色是使用大量的接口。它的主要接口都在org.dom4j里面定义:
魂牵梦萦
魂牵梦萦
魂牵梦萦
Attribute | 定义了XML的属性。 |
Branch | 指能够包含子节点的节点。如XML元素(Element)和文档(Docuemnts)定义了一个公共的行为 |
CDATA | 定义了XMLCDATA区域 |
CharacterData | 是一个标识接口,标识基于字符的节点。如CDATA,Comment,Text. |
Comment | 定义了XML注释的行为 |
Document | 定义了XML文档 |
DocumentType | 定义XMLDOCTYPE声明 |
Element | 定义XML元素 |
ElementHandler | 定义了Element对象的处理器 |
ElementPath | 被ElementHandler使用,用于取得当前正在处理的路径层次信息 |
Entity | 定义XMLentity |
Node | 为dom4j中所有的XML节点定义了多态行为 |
NodeFilter | 定义了在dom4j节点中产生的一个滤镜或谓词的行为(predicate) |
ProcessingInstruction | 定义XML处理指令 |
Text | 定义XML文本节点 |
Visitor | 用于实现Visitor模式 |
XPath | 在分析一个字符串后会提供一个XPath表达式 |
interfacejava.lang.Cloneable
interfaceorg.dom4j.Node
interfaceorg.dom4j.Attribute
interfaceorg.dom4j.Branch
interfaceorg.dom4j.Document
interfaceorg.dom4j.Element
interfaceorg.dom4j.CharacterData
interfaceorg.dom4j.CDATA
interfaceorg.dom4j.Comment
interfaceorg.dom4j.Text
interfaceorg.dom4j.DocumentType
interfaceorg.dom4j.Entity
interfaceorg.dom4j.ProcessingInstruction
2、XML文档操作1
2.1、读取XML文档:
读写XML文档主要依赖于org.dom4j.io包,有DOMReader和SAXReader两种方式。因为利用了相同的接口,它们的调用方式是一样的。publicstaticDocumentload(Stringfilename){
Documentdocument=null;
try{
SAXReadersaxReader=newSAXReader();
document=saxReader.read(newFile(filename));//读取XML文件,获得document对象
}catch(Exceptionex){
ex.printStackTrace();
}
returndocument;
}
或
publicstaticDocumentload(URLurl){
Documentdocument=null;
try{
SAXReadersaxReader=newSAXReader();
document=saxReader.read(url);//读取XML文件,获得document对象
}catch(Exceptionex){
ex.printStackTrace();
}
returndocument;
}
//读取指定的xml文件之后返回一个Document对象,这个对象代表了整个XML文档,用于各种Dom运算。执照XML文件头所定义的编码来转换。
2.2、获取根节点
根节点是xml分析的开始,任何xml分析工作都需要从根开始Xmlxml=newXml();
Documentdom=xml.load(path+"/"+file);
Elementroot=dom.getRootElement();
2.3、.新增一个节点以及其下的子节点与数据
ElementmenuElement=root.addElement("menu");ElementengNameElement=menuElement.addElement("engName");
engNameElement.setText(catNameEn);
ElementchiNameElement=menuElement.addElement("chiName");
chiNameElement.setText(catName);
2.4、写入XML文件
注意文件操作的包装类是乱码的根源publicstaticbooleandoc2XmlFile(Documentdocument,Stringfilename){
booleanflag=true;
try{
XMLWriterwriter=newXMLWriter(newOutputStreamWriter(newFileOutputStream(filename),"UTF-8"));
writer.write(document);
writer.close();
}catch(Exceptionex){
flag=false;
ex.printStackTrace();
}
System.out.println(flag);
returnflag;
}
Dom4j通过XMLWriter将Document对象表示的XML树写入指定的文件,并使用OutputFormat格式对象指定写入的风格和编码方法。调用OutputFormat.createPrettyPrint()方法可以获得一个默认的prettyprint风格的格式对象。对OutputFormat对象调用setEncoding()方法可以指定XML文件的编码方法。
publicvoidwriteTo(OutputStreamout,Stringencoding)throwsUnsupportedEncodingException,IOException{
OutputFormatformat=OutputFormat.createPrettyPrint();
format.setEncoding("gb2312");
XMLWriterwriter=newXMLWriter(System.out,format);
writer.write(doc);
writer.flush();
return;
}
2.5、遍历xml节点
对Document对象调用getRootElement()方法可以返回代表根节点的Element对象。拥有了一个Element对象后,可以对该对象调用elementIterator()方法获得它的子节点的Element对象们的一个迭代器。使用(Element)iterator.next()方法遍历一个iterator并把每个取出的元素转化为Element类型。publicbooleanisOnly(StringcatNameEn,HttpServletRequestrequest,Stringxml){
booleanflag=true;
Stringpath=request.getRealPath("");
Documentdoc=load(path+"/"+xml);
Elementroot=doc.getRootElement();
for(Iteratori=root.elementIterator();i.hasNext();){
Elementel=(Element)i.next();
if(catNameEn.equals(el.elementTextTrim("engName"))){
flag=false;
break;
}
}
returnflag;
}
2.6、创建xml文件
publicstaticvoidmain(Stringargs[]){StringfileName="c:/text.xml";
Documentdocument=DocumentHelper.createDocument();//建立document对象,用来操作xml文件
ElementbooksElement=document.addElement("books");//建立根节点
booksElement.addComment("Thisisatestfordom4j");//加入一行注释
ElementbookElement=booksElement.addElement("book");//添加一个book节点
bookElement.addAttribute("show","yes");//添加属性内容
ElementtitleElement=bookElement.addElement("title");//添加文本节点
titleElement.setText("ajaxinaction");//添加文本内容
try{
XMLWriterwriter=newXMLWriter(newFileWriter(newFile(fileName)));
writer.close();
}catch(Exceptione){
e.printStackTrace();
}
}
2.7、修改节点属性
publicstaticvoidmodifyXMLFile(){StringoldStr="c:/text.xml";
StringnewStr="c:/text1.xml";
Documentdocument=null;
//修改节点的属性
try{
SAXReadersaxReader=newSAXReader();//用来读取xml文档
document=saxReader.read(newFile(oldStr));//读取xml文档
Listlist=document.selectNodes("/books/book/@show");//用xpath查找节点book的属性
Iteratoriter=list.iterator();
while(iter.hasNext()){
Attributeattribute=(Attribute)iter.next();
if(attribute.getValue().equals("yes"))
attribute.setValue("no");
}
}catch(Exceptione){
e.printStackTrace();
}
//修改节点的内容
try{
SAXReadersaxReader=newSAXReader();//用来读取xml文档
document=saxReader.read(newFile(oldStr));//读取xml文档
Listlist=document.selectNodes("/books/book/title");//用xpath查找节点book的内容
Iteratoriter=list.iterator();
while(iter.hasNext()){
Elementelement=(Element)iter.next();
element.setText("xxx");//设置相应的内容
}
}catch(Exceptione){
e.printStackTrace();
}
try{
XMLWriterwriter=newXMLWriter(newFileWriter(newFile(newStr)));
writer.write(document);
writer.close();
}catch(Exceptionex){
ex.printStackTrace();
}
}
2.8、删除节点
publicstaticvoidremoveNode(){StringoldStr="c:/text.xml";
StringnewStr="c:/text1.xml";
Documentdocument=null;
try{
SAXReadersaxReader=newSAXReader();//用来读取xml文档
document=saxReader.read(newFile(oldStr));//读取xml文档
Listlist=document.selectNodes("/books/book");//用xpath查找对象
Iteratoriter=list.iterator();
while(iter.hasNext()){
ElementbookElement=(Element)iter.next();
//创建迭代器,用来查找要删除的节点,迭代器相当于指针,指向book下所有的title节点
Iteratoriterator=bookElement.elementIterator("title");
while(iterator.hasNext()){
ElementtitleElement=(Element)iterator.next();
if(titleElement.getText().equals("ajaxinaction")){
bookElement.remove(titleElement);
}
}
}
}catch(Exceptione){
e.printStackTrace();
}
try{
XMLWriterwriter=newXMLWriter(newFileWriter(newFile(newStr)));
writer.write(document);
writer.close();
}catch(Exceptionex){
ex.printStackTrace();
}
}
2、XML文档操作2
2.1、Document对象相关
1、读取XML文件,获得document对象.
SAXReaderreader=newSAXReader();
Documentdocument=reader.read(newFile("input.xml"));
2、解析XML形式的文本,得到document对象.
Stringtext="<members></members>";
Documentdocument=DocumentHelper.parseText(text);
3、主动创建document对象.
Documentdocument=DocumentHelper.createDocument();
Elementroot=document.addElement("members");//创建根节点
2.2、节点相关
1、获取文档的根节点.
ElementrootElm=document.getRootElement();
2、取得某节点的单个子节点.
ElementmemberElm=root.element("member");//"member"是节点名
3.取得节点的文字
Stringtext=memberElm.getText();
Stringtext=root.elementText("name");这个是取得根节点下的name字节点的文字.
4.取得某节点下指定名称的所有节点并进行遍历.
Listnodes=rootElm.elements("member");
for(Iteratorit=nodes.iterator();it.hasNext();){
Elementelm=(Element)it.next();
//dosomething
}
5.对某节点下的所有子节点进行遍历.
for(Iteratorit=root.elementIterator();it.hasNext();){
Elementelement=(Element)it.next();
//dosomething
}
6.在某节点下添加子节点.
ElementageElm=newMemberElm.addElement("age");
7.设置节点文字.
ageElm.setText("29");
8.删除某节点.
parentElm.remove(childElm);//childElm是待删除的节点,parentElm是其父节点
9.添加一个CDATA节点.
ElementcontentElm=infoElm.addElement("content");
contentElm.addCDATA(diary.getContent());
2.3、属性相关.
1.取得节点的指定的属性
Elementroot=document.getRootElement();
Attributeattribute=root.attribute("size");//属性名name
2.取得属性的文字
Stringtext=attribute.getText();
Stringtext2=root.element("name").attributeValue("firstname");
//这个是取得根节点下name字节点的firstname属性的值.
3.遍历某节点的所有属性
Elementroot=document.getRootElement();
for(Iteratorit=root.attributeIterator();it.hasNext();){
Attributeattribute=(Attribute)it.next();
Stringtext=attribute.getText();
System.out.println(text);
}
4.设置某节点的属性和文字.
newMemberElm.addAttribute("name","sitinspring");
5.设置属性的文字
Attributeattribute=root.attribute("name");
attribute.setText("sitinspring");
6.删除某属性
Attributeattribute=root.attribute("size");//属性名name
root.remove(attribute);
2.4、将文档写入XML文件.
1.文档中全为英文,不设置编码,直接写入.
XMLWriterwriter=newXMLWriter(newFileWriter("output.xml"));
writer.write(document);
writer.close();
2.文档中含有中文,设置编码格式再写入.
OutputFormatformat=OutputFormat.createPrettyPrint();
format.setEncoding("GBK");//指定XML编码
XMLWriterwriter=newXMLWriter(newFileWriter("output.xml"),format);
writer.write(document);
writer.close();
2.5、字符串与XML的转换
1.将字符串转化为XML
Stringtext="<members><member>sitinspring</member></members>";
Documentdocument=DocumentHelper.parseText(text);
2.将文档或节点的XML转化为字符串.
SAXReaderreader=newSAXReader();
Documentdocument=reader.read(newFile("input.xml"));
Elementroot=document.getRootElement();
StringdocXmlText=document.asXML();
StringrootXmlText=root.asXML();
ElementmemberElm=root.element("member");
StringmemberXmlText=memberElm.asXML();
3、dom4j的事件处理模型涉及的类和接口:
3.1、类:SAXReader
publicvoidaddHandler(Stringpath,ElementHandlerhandler)当解析到path指定的路径时,将调用参数handler指定的处理器。针对不同的节点可以添加多个handler实例。或者调用默认的HandlersetDefaultHandler(ElementHandlerhandler);
3.2、接口ElementHandler
publicvoidonStart(ElementPathpath)该方法在解析到元素的开始标签时被调用。
publicvoidonEnd(ElementPathpath)
该方法在解析到元素的结束标签时被调用
3.3、接口:ElementPath(假设有参数:ElementPathpath)
publicvoidaddHandler(Stringpath,ElementHandler)
该方法与SAXReader类中的addHandler()方法的作用相同。路径path可以是绝对路径(路径以/开头),也可以是相对路径(假设是当前路径的子节点路径)。
publicvoidremoveHandler(Stringpath)
移除指定路径上的ElementHandler实例。路径可以是相对路径,也可以是绝对路径。
publicStringgetPath()
该方法得到当前节点的路径。该方法返回的是完整的绝对路径
publicElementgetCurrent()
该方法得到当前节点。
3.3、Element类
getQName() | 元素的QName对象 |
getNamespace() | 元素所属的Namespace对象 |
getNamespacePrefix() | 元素所属的Namespace对象的prefix |
getNamespaceURI() | 元素所属的Namespace对象的URI |
getName() | 元素的localname |
getQualifiedName() | 元素的qualifiedname |
getText() | 元素所含有的text内容,如果内容为空则返回一个空字符串而不是null |
getTextTrim() | 元素所含有的text内容,其中连续的空格被转化为单个空格,该方法不会返回null |
attributeIterator() | 元素属性的iterator,其中每个元素都是Attribute对象 |
attributeValue() | 元素的某个指定属性所含的值 |
elementIterator() | 元素的子元素的iterator,其中每个元素都是Element对象 |
element() | 元素的某个指定(qualifiedname或者localname)的子元素 |
elementText() | 元素的某个指定(qualifiedname或者localname)的子元素中的text信息 |
getParent | 元素的父元素 |
getPath() | 元素的XPath表达式,其中父元素的qualifiedname和子元素的qualifiedname之间使用"/"分隔 |
isTextOnly() | 是否该元素只含有text或是空元素 |
isRootElement() | 是否该元素是XML树的根节点 |
3.4、类DocumentHelper
DocumentHelper是用来生成生成XML文档的工厂类
4、通过xpath查找指定的节点
采用xpath查找需要引入jaxen-xx-xx.jar,否则会报Listlist=document.selectNodes("/books/book/@show");
4.1、xpath语法
1、选取节点
XPath使用路径表达式在XML文档中选取节点,节点是沿着路径或者step来选取的。常见的路径表达式:
表达式 | 描述 |
nodename | 选取当前节点的所有子节点 |
/ | 从根节点选取 |
// | 从匹配选择的当前节点选择文档中的节点,而不考虑它们的位置 |
. | 选取当前节点 |
.. | 选取当前节点的父节点 |
@ | 选取属性 |
路径表达式 | 结果 |
bookstore | 选取bookstore元素的所有子节点 |
/bookstore | 选取根元素bookstore |
bookstore/book | 选取bookstore下名字为book的所有子元素。 |
//book | 选取所有book子元素,而不管它们在文档中的位置。 |
bookstore//book | 选取bookstore下名字为book的所有后代元素,而不管它们位于bookstore之下的什么位置。 |
//@lang | 选取所有名为lang的属性。 |
2、谓语(Predicates)
谓语用来查找某个特定的节点或者包含某个指定的值的节点。谓语被嵌在方括号中。
实例
常见的谓语的一些路径表达式:
路径表达式 | 结果 |
/bookstore/book[1] | 选取属于bookstore子元素的第一个book元素。 |
/bookstore/book[last()] | 选取属于bookstore子元素的最后一个book元素。 |
/bookstore/book[last()-1] | 选取属于bookstore子元素的倒数第二个book元素。 |
/bookstore/book[position()<3] | 选取最前面的两个属于bookstore元素的子元素的book元素。 |
//title[@lang] | 选取所有拥有名为lang的属性的title元素。 |
//title[@lang='eng'] | 选取所有title元素,要求这些元素拥有值为eng的lang属性。 |
/bookstore/book[price>35.00] | 选取所有bookstore元素的book元素,要求book元素的子元素price元素的值须大于35.00。 |
/bookstore/book[price>35.00]/title | 选取所有bookstore元素中的book元素的title元素,要求book元素的子元素price元素的值须大于35.00 |
3、选取未知节点
XPath通配符可用来选取未知的XML元素。通配符 | 描述 |
* | 匹配任何元素节点 |
@* | 匹配任何属性节点 |
node() | 匹配任何类型的节点 |
路径表达式 | 结果 |
/bookstore/* | 选取bookstore元素的所有子节点 |
//* | 选取文档中的所有元素 |
//title[@*] | 选取所有带有属性的title元素。 |
4、选取若干路径
通过在路径表达式中使用“|”运算符,您可以选取若干个路径。实例
路径表达式 | 结果 |
//book/title|//book/price | 选取所有book元素的title和price元素。 |
//title|//price | 选取所有文档中的title和price元素。 |
/bookstore/book/title|//price | 选取所有属于bookstore元素的book元素的title元素,以及文档中所有的price元素。 |
5、XPath轴
轴可定义某个相对于当前节点的节点集。轴名称 | 结果 |
ancestor | 选取当前节点的所有先辈(父、祖父等) |
ancestor-or-self | 选取当前节点的所有先辈(父、祖父等)以及当前节点本身 |
attribute | 选取当前节点的所有属性 |
child | 选取当前节点的所有子元素。 |
descendant | 选取当前节点的所有后代元素(子、孙等)。 |
descendant-or-self | 选取当前节点的所有后代元素(子、孙等)以及当前节点本身。 |
following | 选取文档中当前节点的结束标签之后的所有节点。 |
namespace | 选取当前节点的所有命名空间节点 |
parent | 选取当前节点的父节点。 |
preceding | 选取文档中当前节点的开始标签之前的所有节点。 |
preceding-sibling | 选取当前节点之前的所有同级节点。 |
self | 选取当前节点。 |
6、路径
位置路径表达式位置路径可以是绝对的,也可以是相对的。
绝对路径起始于正斜杠(/),而相对路径不会这样。在两种情况中,位置路径均包括一个或多个步,每个步均被斜杠分割:
绝对位置路径:
相对位置路径:
/step/step/...
step/step/...
每个步均根据当前节点集之中的节点来进行计算。
步(step)包括:
轴(axis):定义所选节点与当前节点之间的树关系
节点测试(node-test):识别某个轴内部的节点
零个或者更多谓语(predicate):更深入地提炼所选的节点集
步的语法:轴名称::节点测试[谓语]
实例
例子 | 结果 |
child::book | 选取所有属于当前节点的子元素的book节点 |
attribute::lang | 选取当前节点的lang属性 |
child::* | 选取当前节点的所有子元素 |
attribute::* | 选取当前节点的所有属性 |
child::text() | 选取当前节点的所有文本子节点 |
child::node() | 选取当前节点的所有子节点 |
descendant::book | 选取当前节点的所有book后代 |
ancestor::book | 选择当前节点的所有book先辈 |
ancestor-or-self::book | 选取当前节点的所有book先辈以及当前节点(假如此节点是book节点的话) |
child::*/child::price | 选取当前节点的所有price孙。 |
7、XPath运算符
运算符 | 描述 | 实例 | 返回值 |
| | 计算两个节点集 | //book|//cd | 返回所有带有book和ck元素的节点集 |
+ | 加法 | 6+4 | 10 |
- | 减法 | 6-4 | 2 |
* | 乘法 | 6*4 | 24 |
div | 除法 | 8div4 | 2 |
= | 等于 | price=9.80 | 如果price是9.80,则返回true。 如果price是9.90,则返回fasle。 |
!= | 不等于 | price!=9.80 | 如果price是9.90,则返回true。 如果price是9.80,则返回fasle。 |
< | 小于 | price<9.80 | 如果price是9.00,则返回true。 如果price是9.90,则返回fasle。 |
<= | 小于或等于 | price<=9.80 | 如果price是9.00,则返回true。 如果price是9.90,则返回fasle。 |
> | 大于 | price>9.80 | 如果price是9.90,则返回true。 如果price是9.80,则返回fasle。 |
>= | 大于或等于 | price>=9.80 | 如果price是9.90,则返回true。 如果price是9.70,则返回fasle。 |
or | 或 | price=9.80orprice=9.70 | 如果price是9.80,则返回true。 如果price是9.50,则返回fasle。 |
and | 与 | price>9.00andprice<9.90 | 如果price是9.80,则返回true。 如果price是8.50,则返回fasle。 |
mod | 计算除法的余数 | 5mod2 | 1 |
相关文章推荐
- Dom4j 使用简介
- Dom4j下载及使用Dom4j读写XML简介
- Dom4j使用简介
- Dom4j 使用简介
- Dom4j下载及使用Dom4j读写XML简介
- DOM4J使用简介
- Dom4j 使用简介
- 使用Dom4j读写XML简介
- Dom4j下载及使用Dom4j读写XML简介
- Dom4j下载及使用Dom4j读写XML简介
- Dom4j下载及使用Dom4j读写XML简介
- Dom4j使用简介
- DOM4J 使用简介
- Dom4j下载及使用Dom4j读写XML简介
- Dom4j 使用简介
- Dom4j下载及使用Dom4j读写XML简介
- Dom4j下载及使用Dom4j读写XML简介
- Dom4j 使用简介
- dom4j使用简介(转载)
- Dom4j 使用简介