dom4j笔记

来源:互联网 发布:安卓玩pc java游戏 编辑:程序博客网 时间:2024/06/05 02:21

转自http://www.mamicode.com/info-detail-1197564.html

1 DOM4J简介

DOM4J是dom4j.org出品的一个开源XML解析包。Dom4j是一个易用的、开源的库,用于XML,XPath和XSLT。它应用于Java平台,采用了Java集合框架并完全支持DOM,SAX和JAXP。

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

接口类 说明 Attribute Attribute定义了XML的属性 Branch Branch为能够包含子节点的节点如XML元素(Element)和文档(Document)定义了一个公共的行为。 CDATA CDATA定义了XML CDATA区域,XML 文档中的文本通常解析为字符数据,或者(按照文档类型定义术语)称为 PCDATA。XML 的特殊字符(&、< 和 >)在 PCDATA 中可以识别,并用于解析元素名称和实体。CDATA(字符数据)区域被解析器视为数据块,从而允许您在数据流中包含任意字符。CDATA 区域的起始标记是一个特殊的序列 序列。这些标记之间的任何内容都将原封不动地通过 XML 解析器。 CharacterData CharacterData是一个标识接口,标识基本字符的节点。如CDATA,Comment,Test。 Comment Comment定义了XML注释的行为 Doucument 定义了XML文档 DocumentType DocumentType定义XML DOCTYPE声明 Element Element定义了XML元素,即一个XML标签及其内容 ElementHandler DlementHandler定义了Element对象的处理器 ElementPath 被ElementHandler使用,用于取得当前正在处理的路径层次信息 Entity Entity定义XML entity Node Node为所有的dom4j中xml节点定义了多态行为,它是dom4j树中所有节点的根接口 NodeFilter NodeFilter定义了在dom4j节点中产生的一个滤镜或谓词的行为(predicate) ProcessingInstruction ProcessingInstruction定义XML处理指令 Text Text定义XML文本节点 Visitor Vistor用于实现Visitor模式 XPath XPath在分析一个字符串后会提供一个XPath表达式



这里写图片描述

2 dom4j常用操作

2.1 获取类加载目录下的xml文件生成Document对象

//获取类加载文件目录,substring(6)为了去掉path中的file:/前缀String resourcePath = Class.class.getResource("/").toString().substring(6);//读取该路径下的xxx.xml文件生成Document对象SAXReader reader = new SAXReader();//read方法可以从InputStream、File、Url等多种不同的源来读取Document doc = reader.read(new File(resourcePath+"xxx.xml"));//打印document内容System.out.println(doc.asXML());

2.2 读取Root节点

一切XML分析都是从Root元素开始的

doc.getRootElement();

2.3 遍历XML树

DOM4J提供了至少3种遍历节点的方法:

2.3.1 枚举(Iterator)

//枚举所有子节点for(Iterator i=root.elementIterator();i.hasNext();){    Element e=(Element)i.next();}//枚举名称为foo的节点for(Iterator i=root.elementIterator(foo);i.hasNext()){    Element e=(Element)i.next();}//枚举属性for ( Iterator i = root.attributeIterator(); i.hasNext(); ) {    Attribute attribute = (Attribute) i.next();}

2.3.2 递归

    public void treeWalk(){        treeWalk(doc.getRootElement());    }    public void treeWalk(Element e){        for(int i = 0, size = e.nodeCount(); i < size; i++){            Node node = e.node(i);            if(node instanceof Element){                treeWalk((Element)node);            }else{                //do something...            }        }    }

2.3.3 Visitor模式

DOM4J提供对Visitor的支持,这样可以大大缩减代码量,并且清楚易懂。了解设计模式的人都知道,Visitor是GOF设计模式之一。其主要原理就是两种类互相保有对方的引用,并且一种作为Visitor去访问许多Visitable。

    //自定义一个类实现Visitor接口    public class MyVisitor extends org.dom4j.VisitorSupport{        public void visit(Element e){            System.out.println(e.getName());        }        public void visit(Attribute attr){            System.out.println(attr.getName());        }    }    //调用:root.accept(new MyVisitor());

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

2.3.4 XPath支持

DOM4J对XPath有良好的支持,如访问一个节点,可以直接用XPath选择。使用XPath需要添加jaxen的jar包

   public void bar(Document document) {        List list = document.selectNodes( "//foo/bar" );        Node node = document.selectSingleNode("//foo/bar/author");        String name = node.valueOf( "@name" );     }

如果想查找XHTML文档中所有的超链接,下面的代码可以实现:

public void findLinks(Document doc) throws DocumentException{    List list=doc.selectNodes("//a/@href");    for(Iterator iter=list.iterator;iter.next();){        Attribute attr=(Attribute)iter.next();        String url=attr.getValue();    }}

2.4 类型转换

2.4.1 字符串与XML转换

//XML转换为字符串Document doc = getDocument(file);String text = doc.asXML();//字符串转换为XMLString text="<person> <name>James</name> </person>";Document document = DocumentHelper.parseText(text);

2.4.2 用XSLT转换XML

public Document styleDocument(Document doc,String stylesheet) throws Exception{    //load the transformer using JAXP    TransformerFactory factory=TransformerFactory.newInstance();    Transformer transformer=factory.newTransformer(new StreamSource(stylesheet));}    //now lets style the given document    DocumentSource source=new DocumentSource(document);    DocumentResult result=new DocumentResult();    transformer.transform(source,result);    //return the transformed document    Document transformedDoc=result.getDocument();    return transformedDoc;

2.5 通过指定属性获得Element

    //通过属性ID获取根元素下一级元素    public static Element getBigTypeElementById(Document doc,String id){        Element root = doc.getRootElement();        List<Element> elements = new ArrayList();        elements = root.elements();        for(Element e:elements){            if(id.equals(e.attributeValue("id"))){                return e;            }        }        return null;    }

2.6 创建XML

一般创建XML是写文件前的工作,这就像StringBuffer一样容易。

public Document createDocument(){    Document doc=DocumentHelper.createDocument();    Element root=doc.addElement("root");    Element author1=root.addElement("author").addAttribute("name","James").addAttribute("location","UK").addText("James Strachan");    Element author2=root.addElement("author").addAttribute("name","Bob").addAttribute("location","US").addText("Bob McWhirter");}    return doc;

2.7 文件输出

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

    FileWriter out = new FileWriter( "foo.xml" );    document.write(out);

如果你想改变输出的格式,比如美化输出或缩减格式,可以用XMLWriter类

public void write(Document doc) throws IOException{    //指定文件    XMLWriter writer=new XMLWriter(new FileWriter(output.xml));    writer.writer(doc);    writer.close();    //美化格式    OutputFormat format=OutputFormat.creatPrettyPrint();    //指定输出的字符编码格式    format.setEncoding("UTF-8");    writer=new XMLWriter(System.out,format);    writer.writer(doc);    //缩减格式    format=OutputFormat.createCompactFormat();    writer=new XMLWriter(System.out,format);    writer.writer(doc);}

添加于2016.06.12:
使用format.setEncoding(“UTF-8”);指定编码格式后,发现写入硬盘的文件还是乱码。解决方法如下:

//修改前代码OutputFormat format=OutputFormat.creatPrettyPrint();format.setEncoding("UTF-8");XMLWriter writer=new XMLWriter(new FileWriter(new File(filePath)),format);writer.write(doc);//修改后代码OutputFormat format=OutputFormat.createPrettyPrint();format.setEncoding("UTF-8");//用FileOutputStream字节流代替FileWriter字符流即可FileOutputStream fos = new FileOutputStream(new File(filePath));XMLWriter writer=new XMLWriter(fos,format);writer.write(doc);

3 java web前后端交互

3.1 java返回xml类型的数据给javascript

java文件中:

HttpServletResponse resp = ServletActionContext.getResponse();resp.setContentType("text/xml; charset=UTF-8");resp.setHeader("Cache-Control", "no-cache");resp.setHeader("Pragma", "no-cache");resp.setDateHeader("Expires", 0);try {    out=resp.getWriter();    Document document = XMLUtil.getDocument(xmlFilePath);    out.write(document.asXML());    out.flush();    out.close();} catch (IOException e) {    // TODO Auto-generated catch block    e.printStackTrace();}finally{    if(out!=null){        out.close();    }}

javascript文件:

$.ajax(    url:"xxx",    dataType:'xml',    type:'POST',    success:function(xml){        $(xml).find("tagName").each(function(i,n){            xxx;        });    });