用Dom4j和SAX解析配置文件成java Bean对象

用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 来完成这个任务!
  


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值