• XML编程总结(四)——使用dom4j方式操作xml


    (四)使用dom4j方式操作xml

    dom4j是解析XML的一种开源API,是jdom的升级品,用来读写XML文档。它具有性能优异、功能强大和极易使用的特点,它的性能超过sun公司官方的dom技术。dom4j对Xpath有良好的支持(使用xpath时需要导入jaxen的jar包),dom4j最大的特色使用大量的接口。使用dom4j时需要导入dom4j-xxx.jar包。

    Attribute ——Attribute定义了XML的属性

    Branch ——Branch为能够包含子节点的节点如XML元素(Element)和文档(Docuemnts)定义了一个公共的行为,

    CDATA ——CDATA 定义了XML CDATA 区域

    CharacterData——CharacterData是一个标识接口,标识基于字符的节点。如CDATA,Comment, Text.

    Comment—— Comment 定义了XML注释的行为

    Document—— 定义了XML文档

    DocumentType—— DocumentType 定义XML DOCTYPE声明

    Element—— Element定义XML 元素

    ElementHandler ——ElementHandler定义了 Element 对象的处理器

    ElementPath 被 ElementHandler 使用,用于取得当前正在处理的路径层次信息

    Entity ——Entity定义 XML entity

    Node ——Node为所有的dom4j中XML节点定义了多态行为

    NodeFilter ——NodeFilter 定义了在dom4j节点中产生的一个滤镜或谓词的行为(predicate)

    ProcessingInstruction ——ProcessingInstruction 定义 XML 处理指令.

    Text ——Text 定义XML文本节点.

    Visitor—— Visitor 用于实现Visitor模式.

    XPath ——XPath 在分析一个字符串后会提供一个Xpath表达式

    测试类代码:

      1 public class Dom4jTest {
      2     private Document doc;
      3 
      4     @Before
      5     public void setUp() throws Exception {
      6         // 获得xml文档的输入流对象
      7         InputStream is = Dom4jTest.class.getClassLoader().getResourceAsStream("books.xml");
      8         // 创建SAXReader对象
      9         SAXReader reader = new SAXReader();
     10         // 通过流对象解析xml文档为Document对象
     11         doc = reader.read(is);
     12     }
     13 
     14     /**
     15      * 使用节点迭代器查询元素
     16      * @throws Exception
     17      */
     18     @Test
     19     public void testRetrieve() throws Exception {        
     20         //获得文档的根节点
     21         Element rootElement = doc.getRootElement();
     22         Iterator iterator = rootElement.elementIterator();
     23         while(iterator.hasNext()){
     24             //获得子节点,先转换为Element,有更多的方法
     25             Element element = (Element) iterator.next();
     26             String value = element.attributeValue("category");
     27             //获得属性为CHILDREN的book节点
     28             if("CHILDREN".equals(value)){
     29                 //获得book节点的迭代器
     30                 Iterator childIterator = element.elementIterator();
     31                 while(childIterator.hasNext()){
     32                     Node node = (Node) childIterator.next();
     33                     //获取子节点的名称
     34                     String name = node.getName();
     35                     if("price".equals(name)){
     36                         //获取节点的文本
     37                         String text = node.getText();
     38                         System.out.println(text);
     39                     }
     40                 }
     41             }
     42         }
     43     }
     44     
     45     /**
     46      * 使用访问器来读取xml文档节点
     47      * @throws Exception
     48      */
     49     @Test
     50     public void testRetrieveByVisitor() throws Exception{
     51         //获得xml文档的输入流对象
     52         InputStream is = Dom4jTest.class.getClassLoader().getResourceAsStream("books.xml");
     53         // 创建SAXReader对象
     54         SAXReader reader = new SAXReader();
     55         // 通过流对象解析xml文档为Document对象
     56         Document doc = reader.read(is);
     57         // 获得文档的根节点
     58         Element rootElement = doc.getRootElement();
     59         //创建自定义的Visitor对象
     60         Visitor visitor = new DomVisitor();
     61         //使用visitor查询文档
     62         rootElement.accept(visitor);
     63     }
     64     
     65     /**
     66      * 创建新的xml文档
     67      * @throws Exception
     68      */
     69     @Test
     70     public void testCreate() throws Exception{
     71         //第一种,创建Document的方法(org.dom4j.Document)
     72         //第一种创建方式是对第二种创建方式的封装
     73         Document document = DocumentHelper.createDocument();
     74         //第二种,创建Document的方法(org.dom4j.Document)
     75         //Document doc = DocumentFactory.getInstance().createDocument();
     76         
     77         //创建根元素节点
     78         Element rootElement = document.addElement("bookstore");
     79         //创建book节点及其子节点
     80         Element bookElement = rootElement.addElement("book");
     81         bookElement.addAttribute("CATEGORY", "CODING");
     82         Element title=bookElement.addElement("title");
     83         title.setText("JAVA CODING");
     84         Element author=bookElement.addElement("author");
     85         author.setText("zs");
     86         Element year=bookElement.addElement("year");
     87         year.setText("2010");
     88         Element price=bookElement.addElement("price");
     89         price.setText("69");
     90         //打印到控制台
     91         writeToConsole(document);
     92         //输出到文件
     93         writeToFile(document);
     94     }
     95     
     96     //输出到文件
     97     private void writeToFile(Document document) throws IOException {
     98         //创建美化格式
     99         OutputFormat format=OutputFormat.createPrettyPrint();
    100         XMLWriter writer=new XMLWriter
    101                 (new FileWriter(new File("abook.xml")),format);
    102         writer.write(document);
    103         //关闭writer就会清空缓存
    104         writer.close();
    105     }
    106 
    107     //打印到控制台
    108     private void writeToConsole(Document document) throws IOException {
    109         //创建输出字符流
    110         PrintWriter writer=new PrintWriter(System.out);
    111         document.write(writer);
    112         //关闭writer就会清空缓存,才会输出来
    113         writer.close();
    114     }
    115     
    116     /**
    117      * 使用XPath查找节点,xpath序号从1开始
    118      * 要使用dom4j的xpath支持,需要导入jaxen包
    119      */
    120     @Test
    121     public void testXPath() throws Exception{
    122         //获得属性web的book节点
    123         Node node = doc.selectSingleNode("//book[@category='WEB']");
    124         //获得所有的book节点
    125         List nodes = doc.selectNodes("//book");
    126         //获得第2个book节点
    127         Node secondNode = doc.selectSingleNode("//book[2]");
    128         //将xml片段转换为字符串
    129         String xml = secondNode.asXML();
    130         System.out.println(xml);
    131     }
    132     
    133     @Test
    134     public void testStringToXML() throws Exception{
    135         String xmlString="<book category='CHILDREN'><title lang='en'>Harry Potter</title>"+
    136                     "<author>J K. Rowling</author><year>2005</year><price>29.99</price></book>";
    137         //转换字符串为xml片段
    138         Document document = DocumentHelper.parseText(xmlString);
    139         //打印到控制台
    140         writeToConsole(document);
    141     }
    142     
    143     /**
    144      * 删除指定的节点
    145      * @throws Exception
    146      */
    147     @Test
    148     public void testDelete() throws Exception{
    149         //获得最后一个book节点
    150         Node node = doc.selectSingleNode("//book[4]");
    151         //获得最后一个book节点的父节点
    152         Element parent = node.getParent();
    153         //删除最后一个book节点,删除需要使用父节点来删除,删除成功则返回true
    154         Boolean flag=parent.remove(node);
    155         System.out.println(flag);
    156         //打印到控制台
    157         writeToConsole(doc);
    158     }
    159     
    160     /**
    161      * 修改指定的节点
    162      * @throws Exception
    163      */
    164     @Test
    165     public void testUpdate() throws Exception{
    166         //获得第一个book节点的price和year
    167         Node yearNode = doc.selectSingleNode("//book[1]/year");
    168         yearNode.setText("2015");
    169         Node priceNode = doc.selectSingleNode("//book[1]/price");
    170         priceNode.setText("59.00");
    171         //修改后的xml文档打印到控制台
    172         writeToConsole(doc);
    173     }
    174 }

    Visitor子类代码:

     1 public class DomVisitor extends VisitorSupport {
     2     // 使用栈这个数据结构来保存
     3     private Stack<String> stack = new Stack<String>();
     4 
     5     // 数据
     6     private String attr;
     7     private String title;
     8     private String author;
     9     private String year;
    10     private double price;
    11 
    12     @Override
    13     public void visit(Document document) {
    14     }
    15 
    16     @Override
    17     public void visit(Element node) {
    18 //        System.out.println("element node-----------");
    19 
    20         //获得节点的名称
    21         String name = node.getName();
    22         if("book".equals(name)){
    23             if(!stack.isEmpty()){
    24                 stack.clear();
    25             }
    26             stack.push(name);
    27         }else if("title".equals(node.getName())){
    28             stack.push(name);
    29         }else if("author".equals(name)){
    30             stack.push(name);
    31         }else if("year".equals(name)){
    32             stack.push(name);
    33         }else if("price".equals(name)){
    34             stack.push(name);
    35         }
    36     }
    37 
    38     @Override
    39     public void visit(Attribute node) {
    40 //        System.out.println("attribute node-----");
    41         
    42         String peek = stack.peek();
    43         if("book".equals(peek)){
    44             String value = node.getValue();
    45             if("CHILDREN".equals(value)){
    46                 attr=value;
    47             }
    48         }
    49     }
    50 
    51     @Override
    52     public void visit(Text node) {
    53 //        System.out.println("text node--------");
    54         //注意:一个标签元素前后都有一个文本节点
    55         if("CHILDREN".equals(attr)){
    56             String tag = stack.peek();
    57             if ("title".equals(tag) && null==title)
    58             {
    59                 title = node.getText();
    60             }
    61             else if ("author".equals(tag) && null==author)
    62             {
    63                 author = node.getText();
    64             }
    65             else if ("year".equals(tag) && null==year)
    66             {
    67                 year = node.getText();
    68             }
    69             else if ("price".equals(tag) && price==0)
    70             {
    71                 price = Double.parseDouble(node.getText());
    72                 System.out.println(this.toString());                
    73             }
    74         }        
    75     }
    76 
    77     @Override
    78     public String toString() {
    79         StringBuilder sb=new StringBuilder();
    80         sb.append("book attribute:"+attr);
    81         sb.append("
    ");
    82         sb.append("title:"+title);
    83         sb.append("
    ");
    84         sb.append("author:"+author);
    85         sb.append("
    ");
    86         sb.append("year:"+year);
    87         sb.append("
    ");
    88         sb.append("price:"+price);
    89         sb.append("
    ");
    90         return sb.toString();
    91     }
    92 }

    使用Visitor子类读取文档结果:

    book attribute:CHILDREN

    title:Harry Potter

    author:J K. Rowling

    year:2005

  • 相关阅读:
    Web 请求响应原理(转)
    openstack中的floating ip与阿里云的公网ip
    一起来说 Vim 语
    vsftpd.conf 详解与实例配置
    jquery 放大图片
    jQuery 之 .stop() 方法
    jquery 插件开发
    jquery 之效果
    jquery 之事件 多库共存(noConflict)
    测试网站是共享还是独立ip
  • 原文地址:https://www.cnblogs.com/techlogy/p/5965096.html
Copyright © 2020-2023  润新知