`
m635674608
  • 浏览: 5027736 次
  • 性别: Icon_minigender_1
  • 来自: 南京
社区版块
存档分类
最新评论

Digester解析xml文件

    博客分类:
  • java
 
阅读更多

刚刚学了一下Digester如何解析xml文件,所以记录下来,方便以后查看。

 

    一般用来读取xml文件的工具包有DOM、SAX和JDOM等,但用过的人都知道,它们属于比较底层的API,写起来代码量很大,而且如果修改了xml文件的格式,代码也要做大幅度的改动。而使用Apache Jakarta的Digester,解析XML文件非常方便且不需要过多的关心底层的具体解析过程。Digester本来仅仅是Jakarta Struts中的一个工具,用于处理struts-config.xml配置文件。显然,将XML文件转换成相应的Java对象是一项很通用的功能,这个工具理应具有更广泛的用途,所以很快它就在Jakarta Commons项目(用于提供可重用的Java组件库)中有了一席之地。Digester由"事件"驱动,通过调用预定义的规则操作对象栈,将XML文件转换为Java对象。

    工作原理如下: Digester底层采用SAX(Simple API for XML)析XML文件,所以很自然的,对象转换由"事件"驱动,在遍历每个节点时,检查是否有匹配模式,如果有,则执行规则定义的操作,比如创建特定的Java对象,或调用特定对象的方法等。此处的XML元素根据匹配模式(matching pattern)识别,而相关操作由规则(rule)定义。

    如下xml代码,右边是左边元素对应的匹配模式:

 

[xhtml] view plaincopy
  1. <datasources>          'datasources'   
  2.   <datasource>         'datasources/datasource'   
  3.     <name/>            'datasources/datasource/name'   
  4.     <driver/>          'datasources/datasource/driver'    
  5.   </datasource>   
  6.   <datasource>         'datasources/datasource'   
  7.     <name/>            'datasources/datasource/name'   
  8.     <driver/>          'datasources/datasource/driver'    
  9.   </datasource>   
  10. </datasources>   

 

 

例子1:

下面介绍解析xml文件的代码

 

下面是存放地址及编码的xml文件viewcache.xml(片段):

 

[xhtml] view plaincopy
  1. <?xml version="1.0" encoding="UTF-8" ?>  
  2. <viewcache>  
  3.     <areas>  
  4.         <area>  
  5.             <id>1098</id>  
  6.             <parentId>1001</parentId>  
  7.             <areaType>province</areaType>  
  8.             <name>北京</name>  
  9.             <ordering>1867</ordering>  
  10.         </area>  
  11.         <area>  
  12.             <id>1099</id>  
  13.             <parentId>1098</parentId>  
  14.             <areaType>capital</areaType>  
  15.             <name>北京</name>  
  16.             <ordering>1868</ordering>  
  17.             <phoneArea>010</phoneArea>  
  18.         </area>  
  19.         <area>  
  20.             <id>4476</id>  
  21.             <parentId>1099</parentId>  
  22.             <areaType>county</areaType>   
  23.             <name>北京市朝阳区</name>  
  24.             <ordering>1869</ordering>  
  25.             <phoneArea>010</phoneArea>  
  26.         </area>  
  27.         <area>  
  28.             <id>4477</id>  
  29.             <parentId>1099</parentId>  
  30.             <areaType>county</areaType>  
  31.             <name>北京市崇文区</name>  
  32.             <ordering>1870</ordering>  
  33.             <phoneArea>010</phoneArea>  
  34.         </area>  
  35.         <area>  
  36.             <id>4478</id>  
  37.             <parentId>1099</parentId>  
  38.             <areaType>county</areaType>  
  39.             <name>北京市大兴区</name>  
  40.             <ordering>1871</ordering>  
  41.             <phoneArea>010</phoneArea>  
  42.         </area>  
  43.     </areas>  
  44. </viewcache>  

 

此xml文件分3层结构,分别为:

<viewcache>节点 其下包含1个<areas>节点

<areas>节点 其下包含多个<area>节点

<area>节点,其下包含各种信息节点 : 如:<id> 、<name>等。 

我们的操作目标是把area中的信息节点的内容提取出来。 
把每个<arrea>看做为一个对象,<area>中信息节点的内容为对象中的元素。 
设定一个类Area.java 其内容如下: 

 

[java] view plaincopy
  1. public class Area {  
  2.     private int    id;  
  3.     private String name;  
  4.     private String areaType;  
  5.     private int    parentId;  
  6.     private int    ordering;  
  7.     private String zip;  
  8.       
  9.     private String phoneArea;  
  10.       
  11.     public int getOrdering() {  
  12.         return ordering;  
  13.     }  
  14.     public void setOrdering(int ordering) {  
  15.         this.ordering = ordering;  
  16.     }  
  17.     public String getAreaType() {  
  18.         return areaType;  
  19.     }  
  20.     public void setAreaType(String areaType) {  
  21.         this.areaType = areaType;  
  22.     }  
  23.     public int getId() {  
  24.         return id;  
  25.     }  
  26.     public void setId(int id) {  
  27.         this.id = id;  
  28.     }  
  29.     public String getName() {  
  30.         return name;  
  31.     }  
  32.     public void setName(String name) {  
  33.         this.name = name;  
  34.     }  
  35.     public int getParentId() {  
  36.         return parentId;  
  37.     }  
  38.     public void setParentId(int parentId) {  
  39.         this.parentId = parentId;  
  40.     }  
  41.       
  42.     public String getZip() {  
  43.         return zip;  
  44.     }  
  45.       
  46.     public void setZip(String zip) {  
  47.         this.zip = zip;  
  48.     }  
  49.       
  50.     public String getPhoneArea() {  
  51.         return phoneArea;  
  52.     }  
  53.       
  54.     public void setPhoneArea(String phoneArea) {  
  55.         this.phoneArea = phoneArea;  
  56.     }  
  57. }  

 

 

创建一个ViewCache类,用来保存解析后的所有对象:

 

[java] view plaincopy
  1. public class ViewCache {  
  2.     private List areaList             = new ArrayList();  
  3.     public List getAreaList() {  
  4.         return areaList;  
  5.     }  
  6.     public void setAreaList(List areaList) {  
  7.         this.areaList = areaList;  
  8.     }  
  9.       
  10.     // 供Digester调用的方法  
  11.     public void addArea(Area area) {  
  12.         this.areaList.add(area);  
  13.     }  
  14. }  

 

 

创建一个类AreaDigester,对xml文件进行解析:

 

  1. public class AreaDigester {  
  2.       
  3.     public ViewCache digester() throws Exception {  
  4.         Digester digester = new Digester();  
  5.         digester.setValidating(false);  
  6.         digester.addObjectCreate("viewcache/areas", ViewCache.class);  
  7.         // 指明匹配模式和要创建的类   
  8.         digester.addObjectCreate("viewcache/areas/area", Area.class);  
  9.         // 设置对象属性,与xml文件对应,不设置则是默认  
  10.         digester.addBeanPropertySetter("viewcache/areas/area/id""id");  
  11.         digester.addBeanPropertySetter("viewcache/areas/area/parentId""parentId");  
  12.         digester.addBeanPropertySetter("viewcache/areas/area/name""name");  
  13.         digester.addBeanPropertySetter("viewcache/areas/area/areaType""areaType");  
  14.         digester.addBeanPropertySetter("viewcache/areas/area/ordering""ordering");  
  15.         digester.addBeanPropertySetter("viewcache/areas/area/zip""zip");  
  16.         digester.addBeanPropertySetter("viewcache/areas/area/phoneArea""phoneArea");  
  17.         // 当移动到下一个标签中时的动作  
  18.         digester.addSetNext("viewcache/areas/area""addArea");  
  19.           
  20.         ViewCache vc = null;  
  21.         try {  
  22.             vc = (ViewCache) digester.parse("viewcache.xml");  
  23.         } catch (IOException e) {  
  24.             throw new Exception(e);  
  25.         } catch (SAXException e) {  
  26.             throw new Exception(e);  
  27.         }  
  28.         return vc;  
  29.     }  
  30. }  

 

调用AreaDigester的digester方法,即可把解析后的所有地址对象,存放在ViewCache的list中。

 

例子2:

要解析的xml文件books.xml如下:

 

[xhtml] view plaincopy
  1. <?xml version="1.0" encoding="UTF-8" ?>   
  2. <library name="alibaba图书馆">   
  3.      <book title ="thinking in java"  author="xxx">   
  4.          <chapter>   
  5.              <no>第一章</no>   
  6.              <caption>第一章的标题</caption>   
  7.          </chapter>   
  8.          <chapter>   
  9.              <no>第二章</no>   
  10.              <caption>第二章的标题</caption>   
  11.          </chapter>   
  12.      </book>   
  13.      <book title="effective java"  author="yyy">   
  14.          <chapter>   
  15.              <no>第一章</no>   
  16.              <caption>第一章的标题</caption>   
  17.          </chapter>   
  18.      </book>   
  19. </library>  

 

Library类如下:

 

[java] view plaincopy
  1. public class Library {  
  2.     private String name;  
  3.     private List<Book> bookList = new ArrayList<Book>();  
  4.       
  5.     public String getName() {  
  6.         return name;  
  7.     }  
  8.       
  9.     public void setName(String name) {  
  10.         this.name = name;  
  11.     }  
  12.       
  13.     public List<Book> getBookList() {  
  14.         return bookList;  
  15.     }  
  16.       
  17.     public void addBook(Book book) {  
  18.         bookList.add(book);  
  19.     }  
  20. }  

 

Book类如下:

 

[java] view plaincopy
  1. public class Book {  
  2.   
  3.     private String        title;  
  4.     private String        author;  
  5.     private List<Chapter> chapters = new ArrayList<Chapter>();  
  6.   
  7.     /** 
  8.      * 这个方法,用来演示xml的解析时用的另一种方式 
  9.      * @param title 
  10.      * @param author 
  11.      */  
  12.     public void setBookInfo(String title, String author) {  
  13.         this.title = title;  
  14.         this.author = author;  
  15.     }  
  16.   
  17.     public void addChapter(Chapter chapter) {  
  18.         this.chapters.add(chapter);  
  19.     }  
  20.       
  21.     public String getTitle() {  
  22.         return title;  
  23.     }  
  24.       
  25.     public void setTitle(String title) {  
  26.         this.title = title;  
  27.     }  
  28.       
  29.     public String getAuthor() {  
  30.         return author;  
  31.     }  
  32.       
  33.     public void setAuthor(String author) {  
  34.         this.author = author;  
  35.     }  
  36.       
  37.     public List<Chapter> getChapters() {  
  38.         return chapters;  
  39.     }  
  40.   
  41.     public void setChapters(List<Chapter> chapters) {  
  42.         this.chapters = chapters;  
  43.     }  
  44. }  

 

Chapter类如下:

 

[java] view plaincopy
  1. public class Chapter {  
  2.   
  3.     private String no;  
  4.     private String caption;  
  5.   
  6.     public String getNo() {  
  7.         return no;  
  8.     }  
  9.   
  10.     public void setNo(String no) {  
  11.         this.no = no;  
  12.     }  
  13.   
  14.     public String getCaption() {  
  15.         return caption;  
  16.     }  
  17.   
  18.     public void setCaption(String caption) {  
  19.         this.caption = caption;  
  20.     }  
  21. }  

 

解析xml的类如下:

 

[java] view plaincopy
  1. public class MainTest {  
  2.   
  3.     /** 
  4.      * @param args 
  5.      */  
  6.     public static void main(String[] args) {  
  7.         // 建立一个Digester对象  
  8.         Digester digester = new Digester();  
  9.         //指定它不要用DTD验证XML文档的合法性——这是因为我们没有为XML文档定义DTD  
  10.         digester.setValidating(false);  
  11.         // 从library标签开始解析,并新建一个Library对象做为根对象  
  12.         digester.addObjectCreate("library", Library.class);  
  13.         // 根据library标签属性值设置对象的属性,一次可以设置多个属性  
  14.         digester.addSetProperties("library");  
  15.         // 也可以用下面的方法,指定propertyName  
  16.         // digester.addSetProperties("library", "name", "name");  
  17.   
  18.         // -----第1层元素开始  
  19.         digester.addObjectCreate("library/book", Book.class);  
  20.         //digester.addSetProperties("library/book");  
  21.         // 可以用以下三条语句代替  
  22.         digester.addCallMethod("library/book""setBookInfo"2);  
  23.         digester.addCallParam("library/book"0"title");  
  24.         digester.addCallParam("library/book"1"author");  
  25.         /** 
  26.          * addCallParam(String rule, int  paraIndex,String attributeName) 
  27.          * 该方法与addCallMethod配合使用 
  28.          * int paraIndex:表明需要填充的方法形参序号,从 0 开始,方法由addCallMethod指定 
  29.          * String attributeName:指定标签属性名称 
  30.          */  
  31.           
  32.           
  33.         // -----第2层元素开始  
  34.         digester.addObjectCreate("library/book/chapter", Chapter.class);  
  35.         /** addBeanPropertySetter()是将子节点转换为对象的属性,这个方法还可以有第二个参数,当对象的属性名和子节点的名字不一样时用来指定对象的属性名 
  36.             该方法的作用及使用方法类似于addSetProperties,只不过它是用String rule规则所指定标签的值(而不是标签的属性)来调用对象的setter*/  
  37.         digester.addBeanPropertySetter("library/book/chapter/no");  
  38.         // digester.addBeanPropertySetter("library/book/chapter/no", "no");  
  39.           
  40.         /** addCallMethod(String rule,String methodName, int  paraNumber) 方法 
  41.          * 同样是设置对象的属性,但是方式更加灵活,不需要对象具有setter 
  42.          * 当paraNumber = 0时,可以单独使用(表明为标签的值来调用),不然需要配合addCallParam方法 
  43.         */  
  44.         // digester.addBeanPropertySetter("library/book/chapter/caption");  
  45.         // 下面的方法,可以用来代替上一句,作用是一样的   
  46.         digester.addCallMethod("library/book/chapter/caption""setCaption"0);  
  47.   
  48.         // addSetNext()是说在再次遇到匹配节点后, 调用当前对象(Chapter类的对象)的父对象(Book类的对象)的方法,方法参数是当前层元素的对象  
  49.         digester.addSetNext("library/book/chapter""addChapter");  
  50.         // -----第2层元素结束  
  51.   
  52.         digester.addSetNext("library/book""addBook");  
  53.         // -----第1层元素结束  
  54.   
  55.         try {  
  56.             // 解析XML文件,并得到ROOT元素  
  57.             Library library = (Library) digester.parse(MainTest.class.getResourceAsStream("books.xml"));  
  58.             System.out.println(" 图书馆: " + library.getName());  
  59.             System.out.println(" 共藏书: " + library.getBookList().size() + " 本 ");  
  60.             System.out.println(" ***************************** ");  
  61.   
  62.             for (Book book : library.getBookList()) {  
  63.                 System.out.println(" 书名: " + book.getTitle() + "        作者: " + book.getAuthor());  
  64.                 System.out.println(" ------------------------------ ");  
  65.                 // 显示章节  
  66.                 System.out.println(" 共 " + book.getChapters().size() + " 章 ");  
  67.                 for (Chapter chapter : book.getChapters()) {  
  68.                     System.out.println(chapter.getNo() + ": " + chapter.getCaption());  
  69.                 }  
  70.                 System.out.println(" ------------------------------ ");  
  71.             }  
  72.         } catch (IOException e) {  
  73.             e.printStackTrace();  
  74.         } catch (SAXException e) {  
  75.             e.printStackTrace();  
  76.         }  
  77.     }  
  78. }  

 

 

 

例子3:

 

Digester解析xml的规则,除了在java类中描述设置之外,还可以把解析规则放在xml文件中。以例子2中的代码为例,规则在books-rule.xml文件中,内容如下:(The DTD is distributed in the commons-digester.jar. It can be found at org/apache/commons/digester/xmlrules/digester-rules.dtd,通过查看DTD文件,可以知道有哪些标签可以使用)

 

[xhtml] view plaincopy
  1. <?xml version="1.0" encoding="UTF-8" ?>  
  2. <!DOCTYPE digester-rules PUBLIC  
  3.    "-//Jakarta Apache //DTD digester-rules XML V1.0//EN"  
  4.    "digester-rules.dtd">   
  5. <digester-rules>    
  6.     <object-create-rule pattern="library" classname="com.alibaba.chj.digester.Library" />    
  7.     <set-properties-rule pattern="library">    
  8.         <alias attr-name="name" prop-name="name" />    
  9.     </set-properties-rule>    
  10.     <pattern value="library/book">    
  11.         <object-create-rule classname="com.alibaba.chj.digester.Book" />    
  12.         <set-properties-rule />    
  13.         <pattern value="chapter">    
  14.             <object-create-rule classname="com.alibaba.chj.digester.Chapter" />    
  15.             <bean-property-setter-rule pattern="no" propertyname="no" />  
  16.             <bean-property-setter-rule pattern="caption" propertyname="caption" />  
  17.             <set-next-rule methodname="addChapter" />    
  18.         </pattern>       
  19.         <set-next-rule methodname="addBook" />    
  20.     </pattern>    
  21. </digester-rules>    

 

 

解析xml类的代码,修改为:

 

[java] view plaincopy
  1. public class MainTest {  
  2.   
  3.     /** 
  4.      * @param args 
  5.      */  
  6.     public static void main(String[] args) {  
  7.         try {      
  8.             Digester digester = DigesterLoader.createDigester(DigesterXmlRuleTest.class.getResource("books-rule.xml"));      
  9.             Library library = (Library) digester.parse(DigesterXmlRuleTest.class.getResourceAsStream("books.xml"));      
  10.             System.out.println(" 图书馆: " + library.getName());  
  11.             System.out.println(" 共藏书: " + library.getBookList().size() + " 本 ");  
  12.             System.out.println(" ***************************** ");  
  13.   
  14.             for (Book book : library.getBookList()) {  
  15.                 System.out.println(" 书名: " + book.getTitle() + "        作者: " + book.getAuthor());  
  16.                 System.out.println(" ------------------------------ ");  
  17.                 // 显示章节  
  18.                 System.out.println(" 共 " + book.getChapters().size() + " 章 ");  
  19.                 for (Chapter chapter : book.getChapters()) {  
  20.                     System.out.println(chapter.getNo() + ": " + chapter.getCaption());  
  21.                 }  
  22.                 System.out.println(" ------------------------------ ");  
  23.             }     
  24.         } catch (IOException e) {  
  25.             e.printStackTrace();  
  26.         } catch (SAXException e) {  
  27.             e.printStackTrace();  
  28.         }   
  29.     }  
  30. }  

 

用于规则放在xml文件中,所以解析的类,显得更加简洁一些。

 

 

Digester FAQ: http://wiki.apache.org/commons/Digester/FAQ

版权声明:本文为博主原创文章,未经博主允许不得转载。

http://blog.csdn.net/caihaijiang/article/details/5944955

v

分享到:
评论

相关推荐

    Digester解析XML文件

    本文将深入探讨如何使用Digester解析XML文件,以及在实际项目中如何应用。 首先,让我们了解什么是Apache Commons Digester。这是一个Java库,它的主要功能是读取XML文件,并基于一系列预先定义的规则(Rule),...

    使用Digester解析XML文档示例

    4. **解析XML文件**:使用Digester解析XML文件,并根据定义的规则创建Java对象。 #### 五、总结 通过上述介绍可以看出,Digester是一个非常有用的工具,它可以大大简化XML解析的过程。在实际开发中,尤其是处理...

    利用commons-digester解析xml

    标题“利用commons-digester解析XML”涉及到的是Java开发中的一种处理XML文档的工具——Apache Commons Digester。这个库提供了一种方便的方式来映射XML文档结构到Java对象,从而简化了XML数据的处理过程。 Apache ...

    digester解析XML文件实例

    这个"digester解析XML文件实例"是一个很好的学习资源,帮助开发者理解如何在实际项目中运用Digester。 首先,我们要了解Digester的基本工作原理。Digester通过定义一系列规则(Rules),当解析到XML文档中特定的...

    digester解析xml的问题.pdf

    3. **解析 XML**:创建好 Digester 实例后,使用 `parse` 方法读取 XML 文件并执行预定义的规则。代码示例如下: ```java Digester digester = new Digester(); digester.setValidating(false); // 关闭验证,...

    java反射,Digester解析xml文档

    3. **解析XML**:使用 Digester 的 `parse()` 方法读取XML文件,根据预先定义的规则进行处理。 4. **结果处理**:最后,Digester会生成一个对象模型,代表了XML文档的内容。 以下是一个简单的 Digester 使用示例: ...

    Digester解析XML

    要使用Digester解析XML文档,首先需要创建一个 `org.apache.commons.digester.Digester` 类的实例,并配置必要的模式和规则,最后调用 `parse()` 方法。 以下是一个简单的示例代码: ```java import org.apache....

    使用Apache的Digester来解析XML文档

    5. **解析XML**:最后,使用配置好的 Digester 对象解析XML文件: ```java Root root = null; try (InputStream is = new FileInputStream("path_to_xml_file.xml")) { root = digester.parse(is); } catch ...

    digester解析xml必备包.rar

    这个“digester解析xml必备包.rar”包含了三个关键的jar包,它们是实现Digester功能所必需的。 1. **commons-logging-1.2.jar**:这是Apache Commons Logging库的版本1.2。它提供了一个抽象层,允许开发者使用多种...

    org.apache.commons.digester解析XML.rar

    这个“org.apache.commons.digester解析XML.rar”压缩包包含了一个测试工程,它演示了如何使用Digester库来解析XML文件并映射到Java对象上。下面将详细介绍这个库的功能、使用方法以及在实际开发中的应用。 1. **...

    Digester解析XML问题.pdf

    在示例代码中, DigesterDriver演示了如何配置 Digester来解析XML文件,创建`Catalog`对象并填充其`Book`和`Magazine`子对象,以及相关的`Article`对象。每个元素的属性通过`addBeanPropertySetter()`设置,而对象...

    Digester解析XML的小例子(对象嵌套)

    在Java开发中,Struts框架提供了一个强大的工具——Digester,用于解析XML文件并自动创建、配置Java对象。本文将详细介绍如何使用Digester处理具有嵌套结构的XML文档,并通过一个具体的实例——"DigesterXmlTest"来...

    digester解析xml 所需jar包

    本篇文章将详细介绍如何使用`Digester`解析XML,以及在使用过程中需要的依赖库。 首先,`Digester`的核心功能是通过定义规则来将XML元素与Java对象的属性或方法关联,这样在解析XML时,可以自动创建和填充Java对象...

    digester解析xml

    《digester解析XML详解》 在Java开发中,XML作为一种数据交换格式,广泛应用于配置文件、数据传输等场景。为了方便地将XML文档解析为Java对象,Apache组织提供了一个名为Digester的工具库,它允许开发者通过规则来...

    Digester java解析xml

    Java中的Digester库是Apache Commons项目的一部分,它提供了一种方便的方式来解析XML文档,并将解析结果映射到Java对象模型上。这个库特别适合于创建简单的XML到Java对象的映射,而不需要编写大量的手动解析代码。在...

    digester 解析xml

    **使用Digester解析XML并验证** 1. **设置 Digester 规则** 在使用Digester之前,我们需要定义一系列规则,告诉Digester在遇到XML文档的哪些元素时执行什么操作。这些规则通常涉及到创建新对象、设置对象属性或者...

    扩展PlugIn插件解析XML

    本文将深入探讨如何通过接口和Digester类来解析XML文件,创建并填充Java对象。 首先,理解 Digester 类的工作原理是至关重要的。Digester 是一个规则驱动的XML解析器,它通过匹配XML文档中的模式(Pattern),执行...

Global site tag (gtag.js) - Google Analytics