package org.noures.framework.modules.util.dom4j;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Iterator;
import java.util.List;
import org.dom4j.Attribute;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.dom4j.Node;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.SAXReader;
import org.dom4j.io.XMLWriter;
public class Dom4jUtil {
/**
* 其中,reader的read方法是重载的,可以从InputStream,File,Url等多种不同的源来读取.
* 得到的Document对象就代表了整个XML. 读取的字符编码是按照XML文件头定义的编码来转换的.
* 如果遇到乱码问题,注意要把各处的编码名称保持一致即可.
*
* @param fileName
* @return
* @throws DocumentException
*/
public Document read(String fileName) throws DocumentException {
SAXReader reader = new SAXReader();
Document document = reader.read(new File(fileName));
return document;
}
/**
* 读取后的第二步就是得到Root节点, 熟悉XML的人都知道,一切XML分析都是从Root元素开始的.
*
* @param doc
* @return
*/
public Element getElement(Document doc) {
return doc.getRootElement();
}
/**
* 1) 枚举(Iterator) 获取所有子节点的迭代
*
* @param doc
*/
public void getAllIterator(Document doc) {
Element root = this.getElement(doc);
// 枚举所有子节点
for (Iterator i = root.elementIterator(); i.hasNext();) {
Element element = (Element) i.next();
String text = element.getText();
System.out.println(text);
// do something
}
}
/**
* 1) 枚举(Iterator) 获取制定节点的迭代
*
* @param doc
* @param fooName
*/
public void getFooIterator(Document doc, String fooName) {
Element root = this.getElement(doc);
// 枚举名称为foo的节点
for (Iterator i = root.elementIterator(fooName); i.hasNext();) {
Element foo = (Element) i.next();
String text = foo.getText();
System.out.println(text);
// do something
}
}
/**
* 1) 枚举(Iterator) 获取某节点的所有属性的迭代
*
* @param doc
*/
public void getAttributeIterator(Document doc) {
Element root = this.getElement(doc);
// 枚举属性
for (Iterator i = root.attributeIterator(); i.hasNext();) {
Attribute attribute = (Attribute) i.next();
String text = attribute.getText();
System.out.println(text);
// do something
}
}
/**
* 2)递归 递归也可以采用Iterator作为枚举手段,但文档中提供了另外的做法
*
* @param doc
*/
public void treeWalk(Document doc) {
Element root = this.getElement(doc);
treeWalk(root);
}
private void treeWalk(Element element) {
for (int i = 0, size = element.nodeCount(); i < size; i++) {
Node node = element.node(i);
if (node instanceof Element) {
treeWalk((Element) node);
} else {
String text = node.getText();
System.out.println(text);
// do something
}
}
}
/**
* 3) Visitor模式
*
* @param doc
*/
public void getVisit(Document doc) {
Element root = this.getElement(doc);
root.accept(new Dom4jVisitorUtil());
}
/**
* DOM4J对XPath有良好的支持,如访问一个节点,可直接用XPath选择。 XPath语法:
* http://www.w3school.com.cn/xpath/xpath_syntax.asp
* nodename 选取此节点的所有子节点。
* / 从根节点选取。
* // 从匹配选择的当前节点选择文档中的节点,而不考虑它们的位置。
* . 选取当前节点。
* .. 选取当前节点的父节点。
* @ 选取属性。
*/
public void bar(Document doc) {
/***********************************************************************
Harry Potter
29.99
Learning XML
39.95
**********************************************************************/
// 选取 bookstore 元素的所有子节点。
List list1 = doc.selectNodes("bookstore");
/*选取根元素 bookstore。
* 注释:假如路径起始于正斜杠( / ),则此路径始终代表到某元素的绝对路径!
*/
List list2 = doc.selectNodes("/bookstore");
//选取属于 bookstore 的子元素的所有 book 元素。
List list3 = doc.selectNodes("bookstore/book");
//选取所有 book 子元素,而不管它们在文档中的位置。
List list4 = doc.selectNodes("//book");
/*选择属于 bookstore 元素的后代的所有 book 元素,
* 而不管它们位于 bookstore 之下的什么位置。
*/
List list5 = doc.selectNodes("bookstore//book");
/**
* 选取名为 lang 的所有属性。
*/
List list6 = doc.selectNodes("//@lang");
}
/**
* 查找XHTML文档中所有的超链接
* @param document
* @throws DocumentException
*/
public void findLinks(Document doc) throws DocumentException {
List list = doc.selectNodes("//a/@href");
for(Iterator i = list.iterator();i.hasNext();){
Attribute attribute = (Attribute) i.next();
String url = attribute.getValue();
}
}
/**
*
* 类名称: Dom4jUtil.java
* @Title: getStringXml
* @Description:XML转字符串
* @param doc
* @return String
* @author NoureWang
* @date Oct 13, 2011
*/
public String getStringXml(Document doc){
return doc.asXML();
}
/**
* 字符串转XML
* @param xml
* @return
* @throws DocumentException
*/
public Document getDocumentXml(String xml) throws DocumentException{
return DocumentHelper.parseText(xml);
}
/**
* 一个简单的输出方法是将一个Document或任何的Node通过write方法输出
* @param doc
* @param xml
* @throws IOException
*/
public void simpleWrite(Document doc,String xml) throws IOException{
FileWriter out = new FileWriter(xml);
doc.write(out);
}
/**
* 如果你想改变输出的格式,比如美化输出或缩减格式,可以用XMLWriter类
* @param document
* @throws IOException
*/
public void formatWrite(Document doc, String xml) throws IOException {
// 指定文件
XMLWriter writer = new XMLWriter(new FileWriter(xml));
writer.write(doc);
writer.close();
// 美化格式
OutputFormat format = OutputFormat.createPrettyPrint();
writer = new XMLWriter(System.out, format);
writer.write(doc);
// 缩减格式
format = OutputFormat.createCompactFormat();
writer = new XMLWriter(System.out, format);
writer.write(doc);
}
/**
* 建立一个XML文档,文档名由输入属性决定
*
* @param filename
* 需建立的文件名
* @return 返回操作结果, 0表失败, 1表成功
*/
public int createXMLFile(String filename) {
/** 返回操作结果, 0表失败, 1表成功 */
int returnValue = 0;
/** 建立document对象 */
Document document = DocumentHelper.createDocument();
/** 建立XML文档的根books */
Element booksElement = document.addElement("books");
/** 加入一行注释 */
booksElement.addComment("This is a test for dom4j, holen, 2004.9.11");
/** 加入第一个book节点 */
Element bookElement = booksElement.addElement("book");
/** 加入show属性内容 */
bookElement.addAttribute("show", "yes");
/** 加入title节点 */
Element titleElement = bookElement.addElement("title");
/** 为title设置内容 */
titleElement.setText("Dom4j Tutorials");
/** 类似的完成后两个book */
bookElement = booksElement.addElement("book");
bookElement.addAttribute("show", "yes");
titleElement = bookElement.addElement("title");
titleElement.setText("Lucene Studing");
bookElement = booksElement.addElement("book");
bookElement.addAttribute("show", "no");
titleElement = bookElement.addElement("title");
titleElement.setText("Lucene in Action");
/** 加入owner节点 */
Element ownerElement = booksElement.addElement("owner");
ownerElement.setText("O'Reilly");
try {
/** 将document中的内容写入文件中 */
XMLWriter writer = new XMLWriter(new FileWriter(new File(filename)));
writer.write(document);
writer.close();
/** 执行成功,需返回1 */
returnValue = 1;
} catch (Exception ex) {
ex.printStackTrace();
}
return returnValue;
}
public static void main(String[] args){
Dom4jUtil domu = new Dom4jUtil();
domu.createXMLFile("test.xml");
}
}
package org.noures.framework.modules.util.dom4j;
import org.dom4j.Attribute;
import org.dom4j.Element;
import org.dom4j.VisitorSupport;
/**
* 最令人兴奋的是DOM4J对Visitor的支持,
* 这样可以大大缩减代码量,并且清楚易懂。
* 了解设计模式的人都知道,Visitor是GOF设计模式之一。
* 其主要原理就是两种类互相保有对方的引用,
* 并且一种作为Visitor去访问许多Visitable。
* 我们来看DOM4J中的Visitor模式(快速文档中没有提供)
* 只需要自定一个类实现Visitor接口即可。
* 调用: root.accept(new MyVisitor())
* Visitor接口提供多种Visit()的重载,根据XML不同的对象,
* 将采用不同的方式来访问。上面是给出的Element和Attribute的简单实现,
* 一般比较常用的就是这两个。
* VisitorSupport是DOM4J提供的默认适配器,Visitor接口的Default Adapter模式,
* 这个模式给出了各种visit(*)的空实现,以便简化代码。
* 注意,这个Visitor是自动遍历所有子节点的。
* 如果是root.accept(MyVisitor),将遍历子节点。
* @author Administrator
*/
public class Dom4jVisitorUtil extends VisitorSupport {
public void visit(Element element){
System.out.println(element.getName());
}
public void visit(Attribute attr){
System.out.println(attr.getName());
}
}
JAVA技术学习 https://www.itkc8.com