SAX解析多层嵌套XML

来源:互联网 发布:淘宝怎么清除缓存 编辑:程序博客网 时间:2024/05/21 12:44

最近工程需要解析多层嵌套XML,没有找到合适的公共解析的,要是一个类自己对应写一个解析方法,岂不累死,于是自己写了个通用的解析类。现在还不是很完善,对子类的解析需要提前指定好子类不能动态解析。

我用的是DefaultHandler来处理XML,里面方法执行过程是

public void startDocument() throws SAXException
第一个执行方法。
public void startElement(String uri, String localName, String qName,   Attributes attributes) throws SAXException
该方法是继第一个方法后第二个执行方法。
public void characters(char[] ch, int start, int length)   throws SAXException
这个是继startElement方法后的执行方法。
该方法中的ch把所解析的xml的所有数据都保存进来,且ch初始化为2K数据。 start是一个节点">"的位置。length就是">"到下一个"<"的长度。
public void endElement(String uri, String localName, String qName)   throws SAXException 
若一个节点,比如<name>michael</name>,在执行完characters后会执行该方法。
如果节点,比如<names><name>michael</name></names>在执行names节点时,不会执行到该方法。
public void endDocument() throws SAXException
最后一个执行方法。

解析类如下:

import java.io.IOException;import java.io.StringReader;import java.lang.reflect.Field;import java.lang.reflect.InvocationTargetException;import java.lang.reflect.Method;import java.lang.reflect.Modifier;import java.lang.reflect.ParameterizedType;import java.lang.reflect.Type;import java.util.List;import java.util.regex.Matcher;import java.util.regex.Pattern;import javax.xml.parsers.ParserConfigurationException;import javax.xml.parsers.SAXParser;import javax.xml.parsers.SAXParserFactory;import org.xml.sax.Attributes;import org.xml.sax.InputSource;import org.xml.sax.SAXException;import org.xml.sax.XMLReader;import org.xml.sax.helpers.DefaultHandler;import com.app.dftr.tzsb.zf.model.WcfCity;import com.app.dftr.tzsb.zf.model.WcfCounty;import com.app.dftr.tzsb.zf.model.WcfRegion;/** *  * 类描述: XML解析类 * * @author CHD * @version  * @Date 日期 :  2014-11-7 时间 : 下午3:46:34 */public class SAXParseXMLTools<T> extends DefaultHandler {private String TAG = SAXParseXMLTools.class.getSimpleName();<span style="white-space:pre"></span>private String content;<span style="white-space:pre"></span>// 解析内容<span style="white-space:pre"></span>private String objName;<span style="white-space:pre"></span>// obj名称<span style="white-space:pre"></span>private Object obj;<span style="white-space:pre"></span>// obj<span style="white-space:pre"></span>private Class<?> cla;<span style="white-space:pre"></span>private ListSets<T> results = null;<span style="white-space:pre"></span>private Field[] cla_fields;<span style="white-space:pre"></span>// obj的所有域<span style="white-space:pre"></span>private Method[] cla_methods;<span style="white-space:pre"></span>// obj的方法<span style="white-space:pre"></span>private String tag_name;<span style="white-space:pre"></span>// 当前标签<span style="white-space:pre"></span>private String super_tag_name;<span style="white-space:pre"></span>// 父级标签<span style="white-space:pre"></span>public ListSets<T> getResults() {<span style="white-space:pre"></span>try {<span style="white-space:pre"></span>XMLReader reader = null;<span style="white-space:pre"></span>SAXParserFactory factory = SAXParserFactory.newInstance();<span style="white-space:pre"></span>reader = factory.newSAXParser().getXMLReader();<span style="white-space:pre"></span>reader.setContentHandler(this);<span style="white-space:pre"></span>reader.parse(new InputSource(new StringReader(content)));<span style="white-space:pre"></span>} catch (Exception e) {<span style="white-space:pre"></span>// TODO: handle exception<span style="white-space:pre"></span>DebugLog.printError(TAG, "解析出现异常" + e.getMessage());<span style="white-space:pre"></span>}<span style="white-space:pre"></span>return results;<span style="white-space:pre"></span>}<span style="white-space:pre"></span>public SAXParseXMLTools(String result, Class<?> clas, String objname) {<span style="white-space:pre"></span>results = new ListSets<T>();<span style="white-space:pre"></span>content = result;<span style="white-space:pre"></span>cla = clas;<span style="white-space:pre"></span>objName = objname;<span style="white-space:pre"></span>try {<span style="white-space:pre"></span>obj = cla.newInstance();<span style="white-space:pre"></span>} catch (InstantiationException e) {<span style="white-space:pre"></span>// TODO Auto-generated catch block<span style="white-space:pre"></span>e.printStackTrace();<span style="white-space:pre"></span>} catch (IllegalAccessException e) {<span style="white-space:pre"></span>// TODO Auto-generated catch block<span style="white-space:pre"></span>e.printStackTrace();<span style="white-space:pre"></span>}<span style="white-space:pre"></span>cla_fields = obj.getClass().getDeclaredFields();// 根据Class对象获取属性<span style="white-space:pre"></span>cla_methods = obj.getClass().getDeclaredMethods();// 根据Class对象获取所有方法<span style="white-space:pre"></span>}<span style="white-space:pre"></span>@Override<span style="white-space:pre"></span>public void startDocument() throws SAXException {<span style="white-space:pre"></span>DebugLog.printInfor(TAG, "开始解析!");<span style="white-space:pre"></span>super.startDocument();<span style="white-space:pre"></span>}<span style="white-space:pre"></span>@Override<span style="white-space:pre"></span>public void endDocument() throws SAXException {<span style="white-space:pre"></span>DebugLog.printInfor(TAG, "解析完成!");<span style="white-space:pre"></span>super.endDocument();<span style="white-space:pre"></span>}<span style="white-space:pre"></span>@Override<span style="white-space:pre"></span>public void startElement(String uri, String localName, String qName,<span style="white-space:pre"></span>Attributes attributes) throws SAXException {<span style="white-space:pre"></span>if (qName.equals(objName)) {<span style="white-space:pre"></span>try {<span style="white-space:pre"></span>obj = cla.newInstance();<span style="white-space:pre"></span>} catch (InstantiationException e) {<span style="white-space:pre"></span>// TODO Auto-generated catch block<span style="white-space:pre"></span>e.printStackTrace();<span style="white-space:pre"></span>} catch (IllegalAccessException e) {<span style="white-space:pre"></span>// TODO Auto-generated catch block<span style="white-space:pre"></span>e.printStackTrace();<span style="white-space:pre"></span>}<span style="white-space:pre"></span>super_tag_name = qName;<span style="white-space:pre"></span>} else {<span style="white-space:pre"></span>tag_name = qName;<span style="white-space:pre"></span>try {<span style="white-space:pre"></span>Field field = obj.getClass().getDeclaredField(tag_name);<span style="white-space:pre"></span>Class fieldClazz = field.getType(); // 得到field的class及类型全路径<span style="white-space:pre"></span>if (fieldClazz.isPrimitive()) { // 【1】 判断是否为基本类型<span style="white-space:pre"></span>}<span style="white-space:pre"></span>if (fieldClazz.getName().startsWith("java.lang")) { // getName()返回field的类型全路径;<span style="white-space:pre"></span>}<span style="white-space:pre"></span>if (fieldClazz.isAssignableFrom(List.class)) // 【2】判断是否为队列<span style="white-space:pre"></span>{<span style="white-space:pre"></span>Type fc = field.getGenericType(); // 关键的地方,如果是List类型,得到其Generic的类型<span style="white-space:pre"></span>if (null != fc) {<span style="white-space:pre"></span>if (fc instanceof ParameterizedType) // 【3】如果是泛型参数的类型<span style="white-space:pre"></span>{<span style="white-space:pre"></span>ParameterizedType pt = (ParameterizedType) fc;<span style="white-space:pre"></span>Class genericClazz = (Class) pt<span style="white-space:pre"></span>.getActualTypeArguments()[0]; // 【4】得到泛型里的class类型对象。<span style="white-space:pre"></span>String regex = "<" + tag_name + ">(.*?)</"<span style="white-space:pre"></span>+ tag_name + ">";<span style="white-space:pre"></span>Pattern pattern = Pattern.compile(regex);<span style="white-space:pre"></span>Matcher matcher = pattern.matcher(content);<span style="white-space:pre"></span>if(matcher.find()) {<span style="white-space:pre"></span>String tempStr = matcher.group();<span style="white-space:pre"></span>results.setNextStr(tempStr); // 队列的字符串<span style="white-space:pre"></span>content = matcher.replaceFirst("");<span style="white-space:pre"></span><span style="white-space:pre"></span>if(tag_name.equals("City")) {<span style="white-space:pre"></span>// 城市<span style="white-space:pre"></span>SAXParseXMLTools<WcfCity> appointHanlder = new SAXParseXMLTools<WcfCity>(<span style="white-space:pre"></span>tempStr, genericClazz,<span style="white-space:pre"></span>genericClazz.getSimpleName());<span style="white-space:pre"></span>ListSets<WcfCity> results = appointHanlder<span style="white-space:pre"></span>.getResults();<span style="white-space:pre"></span><span style="white-space:pre"></span>try {<span style="white-space:pre"></span>Class[] args1 = new Class[1];<span style="white-space:pre"></span>args1[0] = List.class;<span style="white-space:pre"></span>Method tempMethod = obj.getClass().getDeclaredMethod("set" + tag_name, args1);<span style="white-space:pre"></span>tempMethod.invoke(obj, results.getResultSet());<span style="white-space:pre"></span>} catch (Exception e) {<span style="white-space:pre"></span>// TODO Auto-generated catch block<span style="white-space:pre"></span>e.printStackTrace();<span style="white-space:pre"></span>}<span style="white-space:pre"></span>} else if(tag_name.equals("County")) { // 县城<span style="white-space:pre"></span>SAXParseXMLTools<WcfCounty> appointHanlder = new SAXParseXMLTools<WcfCounty>(<span style="white-space:pre"></span>tempStr, genericClazz,<span style="white-space:pre"></span>genericClazz.getSimpleName());<span style="white-space:pre"></span>ListSets<WcfCounty> results = appointHanlder<span style="white-space:pre"></span>.getResults();<span style="white-space:pre"></span><span style="white-space:pre"></span>try {<span style="white-space:pre"></span>Class[] args1 = new Class[1];<span style="white-space:pre"></span>args1[0] = List.class;<span style="white-space:pre"></span>Method tempMethod = obj.getClass().getDeclaredMethod("set" + tag_name, args1);<span style="white-space:pre"></span>tempMethod.invoke(obj, results.getResultSet());<span style="white-space:pre"></span>} catch (Exception e) {<span style="white-space:pre"></span>// TODO Auto-generated catch block<span style="white-space:pre"></span>e.printStackTrace();<span style="white-space:pre"></span>}<span style="white-space:pre"></span>} else if(tag_name.equals("Region")) { // 区域<span style="white-space:pre"></span>SAXParseXMLTools<WcfRegion> appointHanlder = new SAXParseXMLTools<WcfRegion>(<span style="white-space:pre"></span>tempStr, genericClazz,<span style="white-space:pre"></span>genericClazz.getSimpleName());<span style="white-space:pre"></span>ListSets<WcfRegion> results = appointHanlder<span style="white-space:pre"></span>.getResults();<span style="white-space:pre"></span><span style="white-space:pre"></span>try {<span style="white-space:pre"></span>Class[] args1 = new Class[1];<span style="white-space:pre"></span>args1[0] = List.class;<span style="white-space:pre"></span>Method tempMethod = obj.getClass().getDeclaredMethod("set" + tag_name, args1);<span style="white-space:pre"></span>tempMethod.invoke(obj, results.getResultSet());<span style="white-space:pre"></span>} catch (Exception e) {<span style="white-space:pre"></span>// TODO Auto-generated catch block<span style="white-space:pre"></span>e.printStackTrace();<span style="white-space:pre"></span>}<span style="white-space:pre"></span>} else if(tag_name.equals("SecondDeviceType")) { // 区域<span style="white-space:pre"></span>SAXParseXMLTools<WcfSecondDeviceType> appointHanlder = new SAXParseXMLTools<WcfSecondDeviceType>(<span style="white-space:pre"></span>tempStr, genericClazz,<span style="white-space:pre"></span>genericClazz.getSimpleName());<span style="white-space:pre"></span>ListSets<WcfSecondDeviceType> results = appointHanlder<span style="white-space:pre"></span>.getResults();<span style="white-space:pre"></span><span style="white-space:pre"></span>try {<span style="white-space:pre"></span>Class[] args1 = new Class[1];<span style="white-space:pre"></span>args1[0] = List.class;<span style="white-space:pre"></span>Method tempMethod = obj.getClass().getDeclaredMethod("set" + tag_name, args1);<span style="white-space:pre"></span>tempMethod.invoke(obj, results.getResultSet());<span style="white-space:pre"></span>} catch (Exception e) {<span style="white-space:pre"></span>// TODO Auto-generated catch block<span style="white-space:pre"></span>e.printStackTrace();<span style="white-space:pre"></span>}<span style="white-space:pre"></span>}<span style="white-space:pre"></span>}<span style="white-space:pre"></span>}<span style="white-space:pre"></span>}<span style="white-space:pre"></span>}<span style="white-space:pre"></span>} catch (NoSuchFieldException e) {<span style="white-space:pre"></span>// TODO Auto-generated catch block<span style="white-space:pre"></span>e.printStackTrace();<span style="white-space:pre"></span>}<span style="white-space:pre"></span>}<span style="white-space:pre"></span>super.startElement(uri, localName, qName, attributes);<span style="white-space:pre"></span>}<span style="white-space:pre"></span>@Override<span style="white-space:pre"></span>public void endElement(String uri, String localName, String qName)<span style="white-space:pre"></span>throws SAXException {<span style="white-space:pre"></span>if (qName.equals(super_tag_name)) {<span style="white-space:pre"></span>results.getResultSet().add((T) obj);<span style="white-space:pre"></span>}<span style="white-space:pre"></span>super.endElement(uri, localName, qName);<span style="white-space:pre"></span>}<span style="white-space:pre"></span>@Override<span style="white-space:pre"></span>public void characters(char[] ch, int start, int length)<span style="white-space:pre"></span>throws SAXException {<span style="white-space:pre"></span>String temp = new String(ch, start, length);<span style="white-space:pre"></span>if (tag_name.equals("_WcfReturnState") && (0 == results.getResult())) {// 解析头部<span style="white-space:pre"></span>results.setResult(Integer.parseInt(temp));<span style="white-space:pre"></span>} else if (tag_name.equals("_WcfReturnMessage")) {<span style="white-space:pre"></span>results.setMessage(temp);<span style="white-space:pre"></span>}<span style="white-space:pre"></span>if (null != super_tag_name && super_tag_name.equals(objName)) {// 确保在父类下 <span style="white-space:pre"></span>for (Field cla_f : cla_fields) {<span style="white-space:pre"></span>if (cla_f.getName().equals(tag_name)) {<span style="white-space:pre"></span>String value = new String(ch, start, length);<span style="white-space:pre"></span>for (Method cla_method : cla_methods) {<span style="white-space:pre"></span>String meth = cla_method.getName();<span style="white-space:pre"></span>// 匹配set方法<span style="white-space:pre"></span>if (meth != null<span style="white-space:pre"></span>&& "set".equals(meth.substring(0, 3))<span style="white-space:pre"></span>&& Modifier.isPublic(cla_method.getModifiers())<span style="white-space:pre"></span>&& ("set"<span style="white-space:pre"></span>+ Character.toUpperCase(cla_f.getName()<span style="white-space:pre"></span>.charAt(0)) + cla_f.getName()<span style="white-space:pre"></span>.substring(1)).equals(meth)) {<span style="white-space:pre"></span>// 调用set方法并赋值<span style="white-space:pre"></span>try {<span style="white-space:pre"></span>cla_method.invoke(obj, value);<span style="white-space:pre"></span>} catch (IllegalArgumentException e) {<span style="white-space:pre"></span>// TODO Auto-generated catch block<span style="white-space:pre"></span>e.printStackTrace();<span style="white-space:pre"></span>} catch (IllegalAccessException e) {<span style="white-space:pre"></span>// TODO Auto-generated catch block<span style="white-space:pre"></span>e.printStackTrace();<span style="white-space:pre"></span>} catch (InvocationTargetException e) {<span style="white-space:pre"></span>// TODO Auto-generated catch block<span style="white-space:pre"></span>e.printStackTrace();<span style="white-space:pre"></span>}<span style="white-space:pre"></span>}<span style="white-space:pre"></span>}<span style="white-space:pre"></span>}<span style="white-space:pre"></span>}<span style="white-space:pre"></span>}<span style="white-space:pre"></span>super.characters(ch, start, length);<span style="white-space:pre"></span>}}

注释写的很详细。

前端获取list很简洁,两行就ok,

SAXParseXMLTools<WcfEnterprise> appointHanlder = new SAXParseXMLTools<WcfEnterprise>(result, WcfEnterprise.class, WcfEnterprise.class.getSimpleName());ListSets<WcfEnterprise> results = appointHanlder.getResults();



1 0
原创粉丝点击