依据XML定义报文格式解析数据

来源:互联网 发布:天刀血玲珑捏脸数据导 编辑:程序博客网 时间:2024/05/16 09:24

需求:
报文(数据集)中含有多个字段,要解析为多个含有意义的字段。
设计:
1、将报文格式定义在xml中
2、通过格式xml来解析数据
当前体会到此设计的优势:
1、报文格式可在xml中配置。报文格式调整不涉及程序调整。
2、程序可读性强。

实现:
一、自定义xml文件
1、节点标签
2、子节点标签
3、数据标签
4、描述标签
5、起始下标
6、长度标签
example.xml:

<?xml version="1.0" encoding="UTF-8"?><infos><!-- 数据截取模板定义 --><info>        <dataName>data1</dataName>     <desc>数据1</desc>      <startIndex>6</startIndex>   <length>10</length>  </info><infos>

二、读取XML文件解析
1、读取xml,获取Document。

 public static Document getDocument(Class<?> cls, String fileName) throws Exception{    InputStream in = null;             try{        //把要解析的XML文档转化为输入流,方便DOM解析器解析        in = cls.getClassLoader().getResourceAsStream(fileName);        //得到DOM解析器的工厂实例        //从DOM工厂获得DOM解析器           DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();           return builder.parse(in);    }finally{        if(in != null){            in.close();        }    }    return null;}
补充:(1)导入包org.w3c.dom.Document   a. dom,为文档对象模型 (DOM) 提供接口,该模型是 Java API for XML Processing 的组件 API。   具体详见:http://download.oracle.com/technetwork/java/javase/6/docs/zh/api/org/w3c/dom/package-summary.html。   b. Document 接口表示整个HTML、XML。   具体详见:http://download.oracle.com/technetwork/java/javase/6/docs/zh/api/org/w3c/dom/Document.html。   另:   a. javax.swing.text 提供类 HTMLEditorKit 和创建 HTML 文本编辑器的支持类。类相关说明详见:http://download.oracle.com/technetwork/java/javase/6/docs/zh/api/javax/swing/text/package-use.html#javax.swing.text   b. javax.swing.text.Document 作为swing文本组建模型的文本容器。 (2)得到XML文档的根节点      Element rootNode = document.getDocumentElement(); (3)从根节点获取子节点     NodeList nodes = rootNode.getChildNodes(); (4)DOM Document Object Model,也即文档对象模型。     对xml文件进阶操作,用Java W3C DOM 进行XML操作的例子,可详见:     http://blog.csdn.net/cds27/article/details/2139110。 (5)从xml设置到Map     注意:应在类中静态块中,进行初始化。
static{                         setSubTemplateToMap();           }     private static final String SUBTEMPLATEFILENAME = "example.xml";     private static Map subTemplateMap = new HashMap<String, List<Map<String,String>>>();     public static void setSubTemplateToMap(){        try {            Document document = XmlDocumentUtils.getDocument(SUBTEMPLATEFILENAME );            NodeList nodeList = document.getElementsByTagName("info");            List<Map<String,String>> list = new ArrayList<Map<String,String>>();            for ( int i = 0; i < nodeList.getLength(); i++){                 Map<String,String> result = new HashMap<String, String>();                 String dataName = document.getElementsByTagName("dataName").item(i).getFirstChild().getNodeValue();                 String startIndex = document.getElementsByTagName("startIndex").item(i).getFirstChild().getNodeValue();                 String length = document.getElementsByTagName("length").item(i).getFirstChild().getNodeValue();                 if(StringUtils.empty(dataName)){                     throw new Exception("第["+i+"]个"+"dataName"+"标签的内容不能为空");                 }                 if ( StringUtils.empty(startIndex)){                     throw new Exception("第["+i+"]个"+"startIndex"+"标签的内容不能为空");                 }                 if ( StringUtils.empty(length)){                     throw new Exception("第["+i+"]个"+"length"+"标签的内容不能为空");                 }                 result.put("dataName", dataName);                 result.put("startIndex", startIndex);                 result.put("length", length);                 list.add(result);            }            subTemplateMap.put(SUBTEMPLATEFILENAME.substring(0,SUBTEMPLATEFILENAME.lastIndexOf(".")), list);        } catch ( Throwable e ) {            e.printStackTrace();        }    }     /*解析数据*/     public static boolean getStrByTemplateMap(String data,String templateName,Map<String,String> result){        boolean bool = false;        List<Map<String,String>> list = subTemplateMap.get(templateName);//获取数据匹配模板        if(list != null && list.size()>0){            for(Map<String,String> map : list){                try{                        String dataName = map.get("dataName");                        int startIndex = Integer.parseInt(map.get("startIndex"));                        int length = Integer.parseInt(map.get("length"));                        String subData = data.substring(startIndex,startIndex+length).trim();                        result.put(dataName, subData);                }catch(Throwable e){                    //logger.error("通过模板解析数据异常",e);                    if(!bool){                        bool = true;                    }                }            }        }        return bool;    }
补充:a. NodeList getElementsByTagName(String tagName) Document成员方法   按文档顺序返回包含在文档中且具有给定标记名称的所有 Element 的 NodeList。b. int getLength() NodeList类成员方法 获取NodeList的长度,即Node数目。c. Node item(int index) NodeList类成员方法 返回集合中第index个项。   NodeList详见:http://download.oracle.com/technetwork/java/javase/6/docs/zh/api/org/w3c/dom/NodeList.html。d. Node getFirstChild() 此节点的第一个子节点。e. String getNodeValue()此节点的值。注意:a. xml文件要能读取到,可放置在同一目录下。b. 若无日志操作的,可注释掉logger部分。c. 引用的工具类StringUtils,可将其替换为 字符串判NULL或判空字符串。
原创粉丝点击