上海做展会的网站都有哪些,浙江省城乡住房建设网站,网站用哪种语言,网页跳转微信小程序Digester解析XML文件的三种方式 1. Digester解析XML文件的三种方式1.1 作用及依赖jar包 2. 重点和难点3. XML文件4. 通过不同的方式解析这个xml文件4.1 通过java编码方式解析#xff08;javabean存储#xff09;4.2 通过java编码方式解析#xff08;list和map存储#xff0… Digester解析XML文件的三种方式 1. Digester解析XML文件的三种方式1.1 作用及依赖jar包 2. 重点和难点3. XML文件4. 通过不同的方式解析这个xml文件4.1 通过java编码方式解析javabean存储4.2 通过java编码方式解析list和map存储4.3 通过xml配置方式解析4.3.1 OrderConfigRule.xml 配置文件4.3.2 Java解析 5.总结 1. Digester解析XML文件的三种方式
1.1 作用及依赖jar包 首先明白Digester是干什么的它是apache开源项目Commons中的一个子项目用于解析XML文档的工具。Digester底层采用的是SAX解析方式通过遍历XML文档规则来进行处理。项目中有需要将XML文件中的信息解析为我们需要的内容时如java类使用Digester是非常方便的。话不多说本案例使用的jdk版本是1.6。简单的jar包依赖如下 commons-digester-1.8.jarcommons-logging.jarcommons-collections-3.2.1.jarcommons-beanutils-1.7.0.jar
2. 重点和难点 重点理解栈的概念难点当使用addObjectCreate()方法时会创建一个对象进栈许多重要的方法都是相对于栈顶元素或次栈顶元素来进行的。如 addCallMethod(pattern, methodName):调用栈顶元素的指定方法addCallMethod(pattern, methodName, paramCount):调用栈顶元素的指定方法可指定方法的参数个数addCallMethod(pattern, methodName, paramCount, paramTypes):调用栈顶元素的指定方法可指定方法的参数个数类型
3. XML文件
?xml version1.0 encodingUTF-8 ?
OrdersOrder user张三 date2008-11-14 price12279goods id1nameIBM笔记本/nameprice8999/pricecount1/counttotal_price8999/total_price/goodsgoods id2name雅戈尔西服/nameprice1300/pricecount2/counttotal_price2600/total_price/goods/Order
/Orders4. 通过不同的方式解析这个xml文件
4.1 通过java编码方式解析javabean存储 根据这个xml文件的各个节点得出我们可以创建两个javabean来存储解析信息。分别为Order.java和good.java。 // 订单类
package cn.com.bean;import java.util.ArrayList;
/*** Order.java:订单类* author ypykip**/
public class Order {private String user; //对应Order标签中的user属性private String date; //对应Order标签中的date属性private String price; //对应Order标签中的price属性//对应Order标签下的所有good标签private ArrayListGoods goodsList new ArrayListGoods();//省略getter和setter...// 添加商品到订单public void add(Goods goods){this.getGoodsList().add(goods);}// 重写toString()方法方便于观察结果Overridepublic String toString() {return Order [user user , date date , price price , goodsList goodsList.toString() ];}}
// 商品类
package cn.com.bean;package cn.com.bean;/*** Goods.java:商品类* author ypykip**/
public class Goods {private String id;private String name;private String price;private String count;private String total_price;//省略getter和setter...Overridepublic String toString() {return Goods [id id , name name , price price , count count , total_price total_price ];}
}// 解析类
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;import org.apache.commons.digester.Digester;
import org.xml.sax.SAXException;import cn.com.bean.Goods;
import cn.com.bean.Order;/*** title:通过digester的方式来解析Order.xml* author grk* 重点理解栈的概念* 当使用addObjectCreate()方法时创建一个对象进栈* 以下的所有操作有一种情况除外表明调用的方法都是对栈顶元素来讲的除非调用* addSetNext()方法移除栈顶元素并执行次栈顶元素的指定方法* * addCallMethod(pattern, methodName):调用栈顶元素的指定方法* addCallMethod(pattern, methodName, paramCount):调用栈顶元素的指定方法可指定方法的* 参数个数addCallMethod(pattern, methodName, paramCount, paramTypes):调用栈顶元素的* 指定方法可指定方法的参数个数类型* * addCallParam(pattern, paramIndex):默认设置指定paramIndex参数为标签内容* addCallParam(pattern, paramIndex, fromStack):设置指定paramIndex参数为栈顶元素* addCallParam(pattern, paramIndex, stackIndex):设置指定paramIndex参数为* addCallParam(pattern, paramIndex, attributeName):设置指定paramIndex参数为标签属性* attributeName的值 addObjectParam(pattern, paramIndex, paramObj):设置指定paramIndex* 参数为paramObj** addSetNext(pattern, methodName):调用次栈顶元素的methodName方法一般为有一个参数的方法* 将栈顶元素作为入参如list的add方法* */
public class ParseOrder {public static void main(String[] args) {parseByJavaBean();}/*** 使用javaBean进行存储*/public static void parseByJavaBean(){// 1.初始化Digester实例对象Digester digester new Digester();// 2.解析Order标签节点//list进栈栈顶元素的list对象digester.addObjectCreate(Orders, ArrayList.class);//Order实例进栈栈顶元素时Order实例对象digester.addObjectCreate(Orders/Order, Order.class);//设置Order标签的属性digester.addSetProperties(Orders/Order);// 3.解析goods标签节点//Goods实例对象进栈digester.addObjectCreate(Orders/Order/goods, Goods.class);digester.addSetProperties(Orders/Order/goods);//设置goods下的其他标签内容digester.addBeanPropertySetter(Orders/Order/goods/name);digester.addBeanPropertySetter(Orders/Order/goods/price);digester.addBeanPropertySetter(Orders/Order/goods/count);digester.addBeanPropertySetter(Orders/Order/goods/total_price);//Goods对象实例出栈digester.addSetNext(Orders/Order/goods, add);//Order对象实例出栈digester.addSetNext(Orders/Order, add);// 4.加载配置文件String filePath ;filePath System.getProperty(user.dir)/bin/config/Order.xml;File file new File(filePath);// 5.解析try {ArrayList list (ArrayList) digester.parse(file);System.out.println(list.toString());} catch (IOException e) {e.printStackTrace();} catch (SAXException e) {e.printStackTrace();}}
}运行结果 [Order [user张三, date2008-11-14, price12279, goodsList[Goods [id1, nameIBM笔记本, price8999, count1, total_price8999], Goods [id2, name雅戈尔西服, price1300, count2, total_price2600]]]] 4.2 通过java编码方式解析list和map存储 /*** 使用list和map进行存储过程复杂不建议使用*/public static void parseByMap(){Digester digester new Digester();// 1.定义Orders节点规则创建一个List集合digester.addObjectCreate(Orders, ArrayList.class);// 2.定义Orders/Order节点规则创建一个Map集合用来存储属性和内容并将此Map放在上一节点中的Listdigester.addObjectCreate(Orders/Order, HashMap.class);digester.addSetNext(Orders/Order, add);// 3.定义Orders/Order节点的属性digester.addCallMethod(Orders/Order, put, 2);//调用栈顶元素map的put方法digester.addObjectParam(Orders/Order, 0, name);//设置keydigester.addCallParam(Orders/Order, 1, name);//设置valuedigester.addCallMethod(Orders/Order, put, 2);digester.addObjectParam(Orders/Order, 0, date);digester.addCallParam(Orders/Order, 1, date);digester.addCallMethod(Orders/Order, put, 2);digester.addObjectParam(Orders/Order, 0, price);digester.addCallParam(Orders/Order, 1, price);// 4.定义一个List集合用来存储Orders/Order节点下的标签digester.addCallMethod(Orders/Order, put, 2);digester.addObjectCreate(Orders/Order, ArrayList.class);digester.addObjectParam(Orders/Order, 0, goodsList);digester.addCallParam(Orders/Order, 1, true);// 5.定义Orders/Order/goods节点规则分别存储idnamepricecounttotal_price属性或标签digester.addObjectCreate(Orders/Order/goods, HashMap.class);digester.addSetNext(Orders/Order/goods, add);digester.addCallMethod(Orders/Order/goods, put, 2);digester.addObjectParam(Orders/Order/goods, 0, id);digester.addCallParam(Orders/Order/goods, 1, id);digester.addCallMethod(Orders/Order/goods/name, put, 2);digester.addObjectParam(Orders/Order/goods/name, 0, name);digester.addCallParam(Orders/Order/goods/name, 1);digester.addCallMethod(Orders/Order/goods/price, put, 2);digester.addObjectParam(Orders/Order/goods/price, 0, price);digester.addCallParam(Orders/Order/goods/price, 1);digester.addCallMethod(Orders/Order/goods/count, put, 2);digester.addObjectParam(Orders/Order/goods/count, 0, count);digester.addCallParam(Orders/Order/goods/count, 1);digester.addCallMethod(Orders/Order/goods/total_price, put, 2);digester.addObjectParam(Orders/Order/goods/total_price, 0, total_price);digester.addCallParam(Orders/Order/goods/total_price, 1);String filePath System.getProperty(user.dir)/bin/config/Order.xml;System.out.println(filePath);File file new File(filePath);System.out.println(file.getAbsolutePath());try {ArrayList list (ArrayList) digester.parse(file);System.out.println(list.toString());} catch (IOException e) {e.printStackTrace();} catch (SAXException e) {e.printStackTrace();}}4.3 通过xml配置方式解析
4.3.1 OrderConfigRule.xml 配置文件
?xml version1.0 encodingUTF-8?
digester-rulespattern valueOrdersobject-create-rule classnamejava.util.ArrayList / !-- 配置Order标签 --pattern valueOrderobject-create-rule classnamecn.com.bean.Order /set-properties-rule/!-- 配置goods标签 --pattern valuegoodsobject-create-rule classnamecn.com.bean.Goods /set-properties-rulealias attr-nameid prop-nameid /!-- id属性对应javabean的id --/set-properties-rulebean-property-setter-rule patternname propertynamename /!-- name属性对应javabean的name --bean-property-setter-rule patternprice propertynameprice /!-- price标签对应javabean的price --bean-property-setter-rule patterncount propertynamecount /!-- count标签对应javabean的count --bean-property-setter-rule patterntotal_price propertynametotal_price /!-- total_price标签对应javabean的total_price --set-next-rule methodnameadd paramtypecn.com.bean.Goods//patternset-next-rule methodnameadd paramtypecn.com.bean.Order//pattern/pattern
/digester-rules 4.3.2 Java解析
public static void parseByXmlConfig() throws IOException, SAXException, URISyntaxException{// 1.加载规则配置文件URL rule Thread.currentThread().getContextClassLoader().getResource(config/OrderConfigRules.xml);// 2.加载待解析的配置文件Order.xmlReader reader null;try {reader new InputStreamReader(new FileInputStream(new File(System.getProperty(user.dir) /bin/config/Order.xml)), utf-8);} catch (FileNotFoundException e) {e.printStackTrace();}// 3.根据规则配置文件创建Digester实例对象InputSource in new InputSource(new InputStreamReader(new FileInputStream(new File(rule.toURI()))));Digester digester DigesterLoader.createDigester(in);// 4.进行解析并打印结果List list (List) digester.parse(reader);System.out.println(list.toString());try {if(reader ! null){reader.close();}} catch (Exception e) {e.printStackTrace();}}结果 [Order [user张三, date2008-11-14, price12279, goodsList[Goods [id1, nameIBM笔记本, price8999, count1, total_price8999], Goods [id2, name雅戈尔西服, price1300, count2, total_price2600]]]] 5.总结
如果需要调用addSetNext()方法时addObjectCreate()方法和addSetNext()方法最好成对出现首先要知道addSetNext()方法是调用次栈顶元素的方法一般以栈顶元素为参数。如上例中使用list和map的方式进行存储时创建顺序分别是Orders—Order—goods对应的list和map分别是list(Orders)—map(Order)—list(goodsList)—map(goods)。当遇到Orders/Order节点时分别创建了一个map和一个list分别表示订单和商品集合。当遇到 /order 结束标签时需要调用list(Orders)的add()方法,即需要此时的栈顶元素是map(Order)和次栈顶元素是list(Orders)。如果addSetNext()写在了list(goodsList)创建之后此时的栈顶元素和次栈顶元素分别是list(goodsList)map(Order)而map是没有add方法的所以会报错 java.lang.NoSuchMethodException: No such accessible method: add() on object: java.util.HashMap 通过使用java编码和配置规则两种方式都可以实现解析其实两者看上去十分相似熟练了其中一种另一种也就无师自通了