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

需求:
报文(数据集)中含有多个字段,要解析为多个含有意义的字段。
设计:
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或判空字符串。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值