您的位置:首页 > 其它

解析xml之--DOM4J

2006-10-10 16:25 507 查看
1.读取并解析XML文档:
读写XML文档主要依赖于org.dom4j.io包,其中提供DOMReader和SAXReader两类不同方式,而调用方式是一样的。这就是依靠接口的好处。

[align=left]//从文件读取XML,输入文件名,返回XML文档[/align]
[align=left]publicDocumentread(StringfileName)throwsMalformedURLException,DocumentException{[/align]
[align=left]SAXReaderreader=newSAXReader();[/align]
[align=left]Documentdocument=reader.read(newFile(fileName));[/align]
[align=left]returndocument;[/align]
}

其中,reader的read方法是重载的,可以从InputStream,File,Url等多种不同的源来读取。得到的Document对象就带表了整个XML。
根据本人自己的经验,读取的字符编码是按照XML文件头定义的编码来转换。如果遇到乱码问题,注意要把各处的编码名称保持一致即可。

2.取得Root节点
读取后的第二步,就是得到Root节点。熟悉XML的人都知道,一切XML分析都是从Root元素开始的。

[align=left] publicElementgetRootElement(Documentdoc){[/align]
[align=left]returndoc.getRootElement();[/align]
}

2.2访问节点

ListchildrenList=elt.elements();

ListchildrenList=elt.elements("student");

ElementeltChild=elt.element("student");

2.3.访问属性

ListattrList=elt.attributes();

Attributeattr=elt.attribute("sn");

StringattrValue=elt.attributeValue("sn");

2.4.删除元素和属性

ElementeltStu=root.element("student");

root.remove(eltstu);

--------------------------------

etl.remove(elt.attribute("sn"));

3.遍历XML树

DOM4J提供至少3种遍历节点的方法:
1)枚举(Iterator)

[align=left]//枚举所有子节点[/align]
[align=left]for(Iteratori=root.elementIterator();i.hasNext();){[/align]
[align=left]Elementelement=(Element)i.next();[/align]
[align=left]//dosomething[/align]
[align=left]}[/align]
[align=left]//枚举名称为foo的节点[/align]
[align=left]for(Iteratori=root.elementIterator("foo");i.hasNext();){[/align]
[align=left]Elementfoo=(Element)i.next();[/align]
[align=left]//dosomething[/align]
[align=left]}[/align]
[align=left]//枚举属性[/align]
[align=left]for(Iteratori=root.attributeIterator();i.hasNext();){[/align]
[align=left]Attributeattribute=(Attribute)i.next();[/align]
[align=left]//dosomething[/align]
}

2)递归

递归也可以采用Iterator作为枚举手段,但文档中提供了另外的做法

[align=left]publicvoidtreeWalk(){[/align]
[align=left]treeWalk(getRootElement());[/align]
[align=left]}[/align]
[align=left]publicvoidtreeWalk(Elementelement){[/align]
[align=left]for(inti=0,size=element.nodeCount();i<size;i++){[/align]
[align=left]Nodenode=element.node(i);[/align]
[align=left]if(nodeinstanceofElement){[/align]
[align=left]treeWalk((Element)node);[/align]
[align=left]}else{//dosomething....[/align]
[align=left]}[/align]
[align=left]}[/align]
}

3)Visitor模式
最令人兴奋的是DOM4J对Visitor的支持,这样可以大大缩减代码量,并且清楚易懂。了解设计模式的人都知道,Visitor是GOF设计模式之一。其主要原理就是两种类互相保有对方的引用,并且一种作为Visitor去访问许多Visitable。我们来看DOM4J中的Visitor模式(快速文档中没有提供)
只需要自定一个类实现Visitor接口即可。

[align=left] publicclassMyVisitorextendsVisitorSupport{[/align]
[align=left]publicvoidvisit(Elementelement){[/align]
[align=left]System.out.println(element.getName());[/align]
[align=left]}[/align]
[align=left]publicvoidvisit(Attributeattr){[/align]
[align=left]System.out.println(attr.getName());[/align]
[align=left]}[/align]
}


调用:root.accept(newMyVisitor())

Visitor接口提供多种Visit()的重载,根据XML不同的对象,将采用不同的方式来访问。上面是给出的Element和Attribute的简单实现,一般比较常用的就是这两个。VisitorSupport是DOM4J提供的默认适配器,Visitor接口的DefaultAdapter模式,这个模式给出了各种visit(*)的空实现,以便简化代码。
注意,这个Visitor是自动遍历所有子节点的。如果是root.accept(MyVisitor),将遍历子节点。我第一次用的时候,认为是需要自己遍历,便在递归中调用Visitor,结果可想而知。

4.XPath支持
DOM4J对XPath有良好的支持,如访问一个节点,可直接用XPath选择。
[align=left][/align]
[align=left]publicvoidbar(Documentdocument){[/align]
[align=left]Listlist=document.selectNodes("//foo/bar");[/align]
[align=left]Nodenode=document.selectSingleNode("//foo/bar/author");[/align]
[align=left]Stringname=node.valueOf("@name");[/align]
[align=left]}[/align]
[align=left][/align]
[align=left]例如,如果你想查找XHTML文档中所有的超链接,下面的代码可以实现:[/align]
[align=left][/align]
[align=left]publicvoidfindLinks(Documentdocument)throwsDocumentException{[/align]
[align=left]Listlist=document.selectNodes("//a/@href");[/align]
[align=left]for(Iteratoriter=list.iterator();iter.hasNext();){[/align]
[align=left]Attributeattribute=(Attribute)iter.next();[/align]
[align=left]Stringurl=attribute.getValue();[/align]
[align=left]}[/align]
[align=left]}[/align]
[align=left][/align]
5.字符串与XML的转换

[align=left]有时候经常要用到字符串转换为XML或反之,[/align]

//XML转字符串

[align=left] Documentdocument=...;[/align]
[align=left]Stringtext=document.asXML();[/align]
[align=left]//字符串转XML[/align]
[align=left]Stringtext="<person><name>James</name></person>";[/align]
Documentdocument=DocumentHelper.parseText(text);

6用XSLT转换XML

[align=left][/align]
[align=left]publicDocumentstyleDocument([/align]
[align=left]Documentdocument,[/align]
[align=left]Stringstylesheet[/align]
[align=left])throwsException{[/align]
[align=left]//loadthetransformerusingJAXP[/align]
[align=left]TransformerFactoryfactory=TransformerFactory.newInstance();[/align]
[align=left]Transformertransformer=factory.newTransformer([/align]
[align=left]newStreamSource(stylesheet)[/align]
[align=left]);[/align]
[align=left]//nowletsstylethegivendocument[/align]
[align=left]DocumentSourcesource=newDocumentSource(document);[/align]
[align=left]DocumentResultresult=newDocumentResult();[/align]
[align=left]transformer.transform(source,result);[/align]
[align=left]//returnthetransformeddocument[/align]
[align=left]DocumenttransformedDoc=result.getDocument();[/align]
[align=left]returntransformedDoc;[/align]
}

7.创建XML
一般创建XML是写文件前的工作,这就像StringBuffer一样容易。
[align=left][/align]
[align=left]publicDocumentcreateDocument(){[/align]
[align=left]Documentdocument=DocumentHelper.createDocument();[/align]
[align=left]Elementroot=document.addElement(root);[/align]
[align=left]Elementauthor1=[/align]
[align=left]root[/align]
[align=left].addElement("author")[/align]
[align=left].addAttribute(name,"James")[/align]
[align=left].addAttribute("location","UK")[/align]
[align=left].addText("JamesStrachan");[/align]
[align=left]Elementauthor2=[/align]
[align=left]root[/align]
[align=left].addElement("author")[/align]
[align=left].addAttribute("name",Bob")[/align]
[align=left].addAttribute("location","US")[/align]
[align=left].addText("BobMcWhirter");[/align]
[align=left]returndocument;[/align]
}

8.文件输出
一个简单的输出方法是将一个Document或任何的Node通过write方法输出

[align=left]FileWriterout=newFileWriter("foo.xml");[/align]
[align=left]document.write(out);[/align]
[align=left][/align]
如果你想改变输出的格式,比如美化输出或缩减格式,可以用XMLWriter类


[align=left]publicvoidwrite(Documentdocument)throwsIOException{[/align]
[align=left]//指定文件[/align]
[align=left]XMLWriterwriter=newXMLWriter([/align]
[align=left]newFileWriter("output.xml")[/align]
[align=left]);[/align]
[align=left]writer.write(document);[/align]
[align=left]writer.close();[/align]
[align=left]//美化格式[/align]
[align=left]OutputFormatformat=OutputFormat.createPrettyPrint();[/align]
[align=left]writer=newXMLWriter(System.out,format);[/align]
[align=left]writer.write(document);[/align]
[align=left]//缩减格式[/align]
[align=left]format=OutputFormat.createCompactFormat();[/align]
[align=left]writer=newXMLWriter(System.out,format);[/align]
[align=left]writer.write(document);[/align]
[align=left]}[/align]
[align=left][/align]
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: