dom4j笔记

转自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这个包里定义:

接口类说明
AttributeAttribute定义了XML的属性
BranchBranch为能够包含子节点的节点如XML元素(Element)和文档(Document)定义了一个公共的行为。
CDATACDATA定义了XML CDATA区域,XML 文档中的文本通常解析为字符数据,或者(按照文档类型定义术语)称为 PCDATA。XML 的特殊字符(&、< 和 >)在 PCDATA 中可以识别,并用于解析元素名称和实体。CDATA(字符数据)区域被解析器视为数据块,从而允许您在数据流中包含任意字符。CDATA 区域的起始标记是一个特殊的序列 序列。这些标记之间的任何内容都将原封不动地通过 XML 解析器。
CharacterDataCharacterData是一个标识接口,标识基本字符的节点。如CDATA,Comment,Test。
CommentComment定义了XML注释的行为
Doucument定义了XML文档
DocumentTypeDocumentType定义XML DOCTYPE声明
ElementElement定义了XML元素,即一个XML标签及其内容
ElementHandlerDlementHandler定义了Element对象的处理器
ElementPath被ElementHandler使用,用于取得当前正在处理的路径层次信息
EntityEntity定义XML entity
NodeNode为所有的dom4j中xml节点定义了多态行为,它是dom4j树中所有节点的根接口
NodeFilterNodeFilter定义了在dom4j节点中产生的一个滤镜或谓词的行为(predicate)
ProcessingInstructionProcessingInstruction定义XML处理指令
TextText定义XML文本节点
VisitorVistor用于实现Visitor模式
XPathXPath在分析一个字符串后会提供一个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();
//字符串转换为XML
String 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;
        });
    }
);
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值