用Dom4j和SAX两种方式将如下配置文件解析成java Bean对象。配置文件(config.xml)如下:
<?xml version="1.0" encoding="UTF-8"?> <Beans> <Bean className="Test" classComment="测试类"> <Field name="name" type="String" comment="名字" /> <Field name="sex" type="Integer" comment="性别" /> </Bean> <Bean className="Test1" classComment="测试类1"> <Field name="name1" type="String" comment="名字1" /> <Field name="sex1" type="Integer" comment="性别1" /> </Bean> </Beans>
首先定义java的三个类Beans、Bean、Field 来承载配置文件的节点,类定义如下:
/** * 总对象 * @author */ public class Beans { private ArrayList<Bean> listBean = new ArrayList<Bean>();; public ArrayList<Bean> getListBean() { return listBean; } public void setListBean(ArrayList<Bean> listBean) { this.listBean = listBean; } } /** * 一个Class Bean * @author * */ public class Bean { private String className;//类名 private String classComment;//类注释 private ArrayList<Field> listField = new ArrayList<Field>(); public String getClassName() { return className; } public void setClassName(String className) { this.className = className; } public String getClassComment() { return classComment; } public void setClassComment(String classComment) { this.classComment = classComment; } public ArrayList<Field> getListField() { return listField; } public void setListField(ArrayList<Field> listField) { this.listField = listField; } } /** * Bean 中的属性对象 * @author * */ public class Field { //类型 private String type; //字段名字 private String name; //字段注释 private String comment; public String getType() { return type; } public void setType(String type) { this.type = type; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getComment() { return comment; } public void setComment(String comment) { this.comment = comment; } }
第一种方式:通过Dom4j的方式解析xml文件:
/** * 将xml格式的字符串转成Beans对象 * @param xml * @return */ public static Beans parseXml(String xml) { Beans returnObj = new Beans(); Document doc = null; try{ doc = DocumentHelper.parseText(xml); Element root = doc.getRootElement(); //obj list List list_el = root.elements(); if(list_el !=null && list_el.size()>0) { for(int i =0;i<list_el.size();i++) { Element obj_el = (Element) list_el.get(i); //解析obj 节点 Bean obj = parseObj(obj_el); returnObj.getListBean().add(obj); } } }catch(Exception e){ e.printStackTrace(); } return returnObj; } /** * 解析Bean节点 * @param obj_el * @return */ private static Bean parseObj(Element obj_el) { Bean obj = new Bean(); obj.setClassName(obj_el.attributeValue("className")); obj.setClassComment(obj_el.attributeValue("classComment")); //获取field 列表 List list_field = obj_el.elements(); if(list_field != null && list_field.size() > 0) { for(int i = 0;i<list_field.size();i++) { Element field_el = (Element)list_field.get(i); //解析field节点 Field field = parseField(field_el); obj.getListField().add(field); } } return obj; } /** * 解析Field属性 * @param field_el * @return */ private static Field parseField(Element field_el) { Field field = new Field(); List list_attr = field_el.attributes(); if(list_attr != null && list_attr.size() > 0) { for(int i=0;i<list_attr.size();i++) { Attribute field_attr = (Attribute)list_attr.get(i); String key = field_attr.getName(); String value = field_attr.getText(); if(key.equals("name")) { field.setName(value); } else if(key.equals("type")) { field.setType(value); } else if(key.equals("comment")) { field.setComment(value); } } } return field; }
第二种方式:通过SAX解析xml文件:
import org.xml.sax.Attributes; import org.xml.sax.SAXException; import org.xml.sax.helpers.DefaultHandler; import com.base.bean.Bean; import com.base.bean.Beans; import com.base.bean.Field; public class MySAXHandler extends DefaultHandler { private Beans beans; private Bean bean; private Field field; private StringBuffer characters; //保存元素内容的缓冲区 /** * 本此解析xml没有用到此方法,因为配置文件xml没有如这种形式的报文 * <Field>abc</Field> */ @Override public void characters(char[] ch, int start, int length) throws SAXException { for(int i = start ; i < start+length ; i++){ switch(ch[i]){ case '\\':characters.append("\\\\");break; case '\r':characters.append("\\r");break; case '\n':characters.append("\\n");break; case '\t':characters.append("\\t");break; case '\"':characters.append("\\\"");break; default : characters.append(ch[i]); } } } /** * 开始解析xml文件的根元素的回调函数 */ @Override public void startDocument() throws SAXException { characters = new StringBuffer(); beans = new Beans(); } /** * 结束解析xml文件的根元素的回调方法 */ @Override public void endDocument() throws SAXException { } /** * 开始解析节点的回调函数 */ @Override public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException { if(qName.equals("Bean")) { bean = new Bean(); bean.setClassComment(attributes.getValue("classComment")); bean.setClassName(attributes.getValue("className")); System.out.println("classComment===>>" + attributes.getValue("classComment")); System.out.println("className===>>" + attributes.getValue("className")); } else if(qName.equals("Field")) { field = new Field(); field.setComment(attributes.getValue("comment")); field.setName(attributes.getValue("name")); field.setType(attributes.getValue("type")); } } /** * 结束解析节点的回调函数 */ @Override public void endElement(String uri, String localName, String qName) throws SAXException { if(qName.equals("Bean")) { beans.getListBean().add(bean); } else if(qName.equals("Field")) { bean.getListField().add(field); } } public Beans getResultBean() { return beans; } } /** * 解析xml文件 * @param in */ public static void getSAXParser(InputStream in) { //创建SAX解析器工厂 SAXParserFactory saxfac=SAXParserFactory.newInstance(); //构造自定义的事件处理器 MySAXHandler hander = new MySAXHandler(); try { //获取SAX解析器实例 javax.xml.parsers.SAXParser saxparser=saxfac.newSAXParser(); saxparser.parse(in,hander); } catch (ParserConfigurationException e1) { e1.printStackTrace(); } catch (SAXException e1) { e1.printStackTrace(); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } }
总结:
1.基于事件的处理的优点和缺点
这种处理的优点非常类似于流媒体的优点。分析能够立即开始,而不是等待所有的数据被处理。而且,由于应用程序只是在读取数据时检查数据,因此不需要将数据存储在 内存中。这对于大型文档来说是个巨大的优点。 事实上,应用程序甚至不必解析整个文档;它可以在某个条件得到满足时停止解析。 一般来说,SAX 还比它的替代者 DOM 快许多。另一方面,由于应用程序没有以任何方式存储数据,使用 SAX 来更改数据或在数据流中往后移是不可能的。
DOM 和基于树的处理
DOM 是处理 XML 数据的传统方法。使用 DOM 时,数据以树状结构的形式被加载到内存中。
同时,就我了解SAX不支持XPATH,而DOM是支持XPATH的;SAX对那种xml节点不确定的情况没办法解析,这时选择VTD来解析将很方便。
2.基于树的处理的优点和缺点
DOM 以及广义的基于树的处理具有几个优点。
首先,由于树在内存中是持久的,因此可以修改它以便应用程序能对数据和结构作出更改。
它还可以在任何时候在树中上下导航,而不是像 SAX 那样是一次性的处理。DOM 使用起来也要简单得多。
另一方面,在内存中构造这样的树涉及大量的开销。大型文件完全占用系统内存容量的情况 鲜见。此外,创建一棵 DOM 树可能是一个缓慢的过程。
3.如何在 SAX 和 DOM 之间选择
选择 DOM 还是选择 SAX,这取决于下面几个因素:
1).应用程序的目的:如果打算对数据作出更改并将它输出为 XML,那么在大多数情况下,DOM 是适当的选择。并不是说使用 SAX 就不能更改数据,但是该过程要复杂得多,因为您必须对数据的一份拷贝而不是对数据本身作出更改。
2).数据容量: 对于大型文件,SAX 是更好的选择。
数据将如何使用:如果只有数据中的少量部分会被使用,那么使用 SAX 来将该部分数据提取到应用程序中可能更好。 另一方面,如果您知道自己以后会回头引用已处理过的大量信息,那么 SAX 也许不是恰当的选择。
3).对速度的需要: SAX 实现通常要比 DOM 实现更快。
SAX 和 DOM 不是相互排斥的,记住这点很重要。您可以使用 DOM 来创建 SAX 事件流,也可以使用 SAX 来创建 DOM 树。事实上,用于创建 DOM 树的大多数解析器实际上都使用 SAX 来完成这个任务!
用Dom4j和SAX解析配置文件成java Bean对象
最新推荐文章于 2021-02-22 07:05:19 发布