大家好,欢迎来到IT知识分享网。
一、Digester简介
//在读到文档开始时调用 void startDocument() //在读到文档结束时调用 void endDocument() // 读到开始标签时调用 void startElement(String uri, String localName, String qName, Attributes attributes) //读到结束标签时调用 void endElement(String uri, String localName, String qName) // 读到文本内容时调用 void characters(char[] ch, int start, int length)
我们在使用SAX做XML解析的时候就只需要在重写这几个方法实现对应的逻辑即可。但是这样没有通用性,新增一个XML就可能需要重新定义一个Handler,太麻烦!这个时候Digester就出山了。
3、digester,对于XML文档中每个元素,Digester对象都会检查它是否需要做预定义事件,所以我们在parse前定义好Digester对象需要执行哪些动作即可。那么这些动作该如何定义?
其实很简单,定义好模式(XML的结构),每一个模式与一个或者多个规则相关联。下面我们看一个简单的XML:
<?xml version="1.0" encoding="UTF-8"?> <server port="8005" shutdown="SHURDOWN"> <service name="Catalina"> <Connector port="8080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" /> </service> </server>
这个XML应该不陌生把,这个XMl根元素是server。
a、模式:根元素的模式和根元素的名称相同,子元素的模式是父元素的模式+“/”+该子元素的名字拼接而成。service元素是sever的子元素,service的元素模式就是server/service,说白了就是一个类似于yml结构化东西。元素模式已经定义好了,下面就剩下规则了。
b、规则:digeser库预定义了很多规则,比如创建对象(addObjectCreate)和设置属性(addSetProperties)、addSetNext等。rule中有begin和end方法,比如当digeser库在读取到某个模式的元素的开始标签时,如果此模式绑定了规则,那么就会执行rule的begin方法。下面看下具体的使用。
二、digester简单使用
public class Server { private String name; private String port; private String shutdown; private List<Service> serviceList = new ArrayList<>(); public void addService(Service service){ System.out.println("Server addService"); serviceList.add(service); } public void play(){ System.out.println("i like pepsi"); } } public class Service { private String name; }
public void parseXml() throws IOException, SAXException { Digester digester = new Digester(); //把当前对象置入栈顶 digester.push(this); //开始设置 Server节点 我是栈顶拉 digester.addObjectCreate("Server", Server.class); digester.addSetProperties("Server"); digester.addCallMethod("Server","play"); digester.addSetNext("Server","setServer"); //同理 读取Service节点,现在我是栈顶 digester.addObjectCreate("Server/Service", Service.class); digester.addSetProperties("Server/Service"); // 调用addService方法 将Service加入Server对象 digester.addSetNext("Server/Service", "addService"); File file = new File("/Users/*/server.xml"); digester.parse(file); }
一个简单的XML就解析成对象了,下面我们重点看下这里面的几个规则:
d、digester预定义规则:
1、创建对象: 当需要digester对象在遇到某个模式的时候创建一个对象,调用addObjectCreate方法即可,这个方法主要的2个参数是:模式和class(类名)。比如我们在匹配到Server的时候想要创建一个Server对象使用addObjectCreate方法即可。
在Degister中维护了一个ArrayStack 栈(protected ArrayStack<Object> stack = new ArrayStack<>()),addObjectCreate创建的对象都会被压入这个栈内(类似于方法栈),可以用于对象之间关系的维护。
2、设置属性:刚才对象已经实例化了,但是属性没有被设值,addSetProperties方法可以为digester对象创建的对象设置属性值。只需要传入一个模式即可。
3、方法调用: addCallMethod方法只需模式和执行的方法名,digester对象匹配到这个规则绑定的模式后,会从digester对象维护的stack栈中取出栈顶的对象,并执行传入的方法。
4、创建对象之间关系:刚上面说到,digester对象内部维护了一个stack栈。上面Server对象内部有一个Service对象,这2个对象一前一后通过addObjectCreate压入,Service在栈顶,它们是通过addSetNext让Service和Server建立关系。
补充:digester对象内部维护了不止一个栈,总共维护了好像3个stack,用于将节点转成的对象的而准备的。分别是对象栈、rule栈(用于对象的操作规则)、param栈(XML节点的值),有兴趣的可以去看下tomcat中对于digester的使用。
到这里digester已经将XML解析成我们想要的对象。这里留个记录方便后续使用,有错误求指正!
免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://haidsoft.com/151737.html