将XML转换为JSON (SAX解析实例)

下面是一个将XML转换为JSON的示例,

通过SAX来解析XML,从而生成相应的JSON字符串

自我感觉还算是一个比较通用的 API ,主要包含3个类

1, ToJsonSAXHandler 类 继承了 DefaultHandler 类,在解析

     XML的过程中负责处理 SAX 事件。代码如下:

 

Java代码  
  1. package org.yjf.xmlToJson;  
      
    import org.xml.sax.Attributes;  
    import org.xml.sax.SAXException;  
    import org.xml.sax.helpers.DefaultHandler;  
      
    public class ToJsonSAXHandler extends DefaultHandler {  
          
        //jsonStringBuilder 保存解析XML时生成的json字符串  
        private StringBuilder jsonStringBuilder ;  
          
        /* 
         *  isProcessing 表示 是否正在解析一个XML 
         *      startDocument 事件发生时设置 isProcessing = true 
         *      startDocument 事件发生时设置 isProcessing = false 
         */  
        private boolean isProcessing;  
          
        /* 
         *  justProcessStartElement 表示 是否刚刚处理完一个 startElement事件 
         *  引入这个标记的作用是为了判断什么时候输出逗号  
         */  
        private boolean justProcessStartElement;  
          
        public ToJsonSAXHandler(){  
            jsonStringBuilder = new StringBuilder();  
        }  
          
        @Override  
        public void startDocument() throws SAXException {  
            /* 
             * 开始解析XML文档时 设定一些解析状态 
             *     设置isProcessing为true,表示XML正在被解析 
             *     设置justProcessStartElement为true,表示刚刚没有处理过 startElement事件 
             */  
            isProcessing = true;  
            justProcessStartElement = true;  
            //清空 jsonStringBuilder 中的字符  
            this.jsonStringBuilder.delete(0, this.jsonStringBuilder.length());  
        }  
          
        @Override  
        public void endDocument() throws SAXException {  
            isProcessing = false;  
        }  
          
        @Override  
        public void startElement(String uri, String localName, String qName,   
                Attributes attrs) throws SAXException {   
            /* 
             * 是否刚刚处理完一个startElement事件 
             *     如果是 则表示这个元素是父元素的第一个元素 。 
             *     如果不是 则表示刚刚处理完一个endElement事件,即这个元素不是父元素的第一个元素 
             */  
            if(!justProcessStartElement){  
                jsonStringBuilder.append(',');  
                justProcessStartElement = true;  
            }  
            jsonStringBuilder.append("{");  
            jsonStringBuilder.append("localName:").append('\"').append(localName).append('\"').append(',');  
            jsonStringBuilder.append("uri:").append('\"').append(uri).append('\"').append(',');  
            jsonStringBuilder.append("qName:").append('\"').append(qName).append('\"').append(',');  
            //将解析出来的元素属性添加到JSON字符串中  
            jsonStringBuilder.append("attrs:{");  
            if(attrs.getLength() > 0){  
                jsonStringBuilder.append(attrs.getLocalName(0)).append(":")  
                    .append(attrs.getValue(0));  
                for(int i = 1 ; i < attrs.getLength() ; i++){  
                    jsonStringBuilder.append(',').append(attrs.getLocalName(i)).append(":")  
                        .append(attrs.getValue(i));  
                }     
            }  
            jsonStringBuilder.append("},");  
            //将解析出来的元素的子元素列表添加到JSON字符串中  
            jsonStringBuilder.append("childElements:[").append('\n');  
        }  
          
        @Override  
        public void endElement(String uri,String localName,String qName)  
                throws SAXException {  
            justProcessStartElement = false;  
            jsonStringBuilder.append("]}").append('\n');  
        }  
      
        @Override  
        public void characters(char[] ch, int begin, int length)   
                throws SAXException {  
            /* 
             * 是否刚刚处理完一个startElement事件 
             *     如果是 则表示这个元素是父元素的第一个元素 。 
             *     如果不是 则表示刚刚处理完一个endElement事件,即这个元素不是父元素的第一个元素 
             */  
            if(!justProcessStartElement){  
                jsonStringBuilder.append(',');  
            }else  
                justProcessStartElement = false;  
              
            jsonStringBuilder.append('\"');  
            for(int i = begin ; i < begin+length ; i++){  
                switch(ch[i]){  
                    case '\'':jsonStringBuilder.append("\\'");break;  
                    case '\"':jsonStringBuilder.append("\\\"");break;  
                    case '\n':jsonStringBuilder.append("\\n");break;  
                    case '\t':jsonStringBuilder.append("\\t");break;  
                    case '\r':jsonStringBuilder.append("\\r");break;  
                    default:  jsonStringBuilder.append(ch[i]);break;  
                }  
            }  
            jsonStringBuilder.append('\"').append('\n');  
        }  
          
        public String getJsonString() throws XMLToJSONException{  
            if(this.isProcessing)  
                throw new XMLToJSONException("getJsonString before resolution is finished");  
            else  
                return jsonStringBuilder.toString();  
        }  
    }  
     

    2,XMLToJSONException 是一个异常类(封装在转换过程中可能产生的异常),代码如下:

     Java代码 

    package org.yjf.xmlToJson; 
    
    public class XMLToJSONException extends Exception { 
    
    private static final long serialVersionUID = 1L; 
    
    public XMLToJSONException(){} 
    public XMLToJSONException(String message){ 
    super(message); 
    } 
    
    }

    3,XMLToJSON  类 是一个将XML转换为JSON字符串的工具类

       Java代码      

package org.yjf.xmlToJson;  
  
import java.io.File;  
import java.io.FileInputStream;  
import java.io.IOException;  
import java.io.StringReader;  
  
import org.xml.sax.InputSource;  
import org.xml.sax.SAXException;  
import org.xml.sax.XMLReader;  
import org.xml.sax.helpers.XMLReaderFactory;  
  
public class XMLToJSON {  
      
    public static String convert(String xmlStr) throws SAXException,  
            IOException, XMLToJSONException {  
        return convert(new InputSource(new StringReader(xmlStr)));  
    }  
  
    public static String convert(File file) throws SAXException,  
            IOException, XMLToJSONException {  
        return convert(new InputSource(new FileInputStream(file)));  
    }  
  
    public static String convert(InputSource inputSource) throws SAXException,  
            IOException, XMLToJSONException {  
        ToJsonSAXHandler handler = new ToJsonSAXHandler();  
        //创建一个 SAX 解析器 ,并设置这个解析器的内容事件处理器 和 错误事件处理器 为 handler  
        XMLReader reader = XMLReaderFactory.createXMLReader();  
        reader.setContentHandler(handler);  
        reader.setErrorHandler(handler);  
        //用 SAX 解析器解析XML输入源  
        reader.parse(inputSource);  
        //返回 ToJsonSAXHandler 中保存的 json字符串  
        return handler.getJsonString();  
    }  
  
}  

    测试类 Test 如下 (因为生成的JSON不包含缩进,所以看起来可能不太直观,所以我用了JSONObject类来打印带有缩进的JSON字符串,同时也验证了转换出来的JSON字符串是一个有效的JSON字符串):

Java代码  
  1. package test;  
      
    import java.io.File;  
    import java.io.IOException;  
      
    import org.json.JSONException;  
    import org.json.JSONObject;  
    import org.xml.sax.SAXException;  
    import org.yjf.xmlToJson.XMLToJSON;  
    import org.yjf.xmlToJson.XMLToJSONException;  
      
    public class Test_1 {  
      
        public static void main(String[] args) throws JSONException,   
                SAXException, IOException, XMLToJSONException{  
            String jsonStr = XMLToJSON.convert(new File("books.xml"));  
            /* 
             * JSONObject 是一个JSON对象的java实现 
             * 可以通过用一个有效的JSON字符串来构造JSON对象 
             * 下面的两行代码通过转换而来的JSON字符串构造了一个JSON对象, 
             * 并且打印出了这个JSON对象的带有缩进的字符串表示 
             */  
            JSONObject jsonObj = new JSONObject(jsonStr);  
            System.out.println(jsonObj.toString(2));  
        }  
      
    }  
     

    books.xml 的内容如下:

   Xml代码  
  1. <?xml version="1.0" encoding="utf-8"?>  
    <books  count="2" xmlns="http://test.org/books">  
        <book id="1" page="1000">  
            <name>Thinking in JAVA</name>  
        </book>  
        <book id="2" page="800">  
            <name>Core JAVA2</name>  
        </book>  
    </books>  

  运行 Test 类输出的JSON字符串 如下:      

{
    "attrs": {"count": 2},
    "childElements": [
        "\n\t",
        {
            "attrs": {
                "id": 1,
                "page": 1000
            },
            "childElements": [
                "\n\t\t",
                {
                    "attrs": {},
                    "childElements": ["Thinking in JAVA"],
                    "localName": "name",
                    "qName": "name",
                    "uri": "http://test.org/books"
                },
                "\n\t"
            ],
            "localName": "book",
            "qName": "book",
            "uri": "http://test.org/books"
        },
        "\n\t",
        {
            "attrs": {
                "id": 2,
                "page": 800
            },
            "childElements": [
                "\n\t\t",
                {
                    "attrs": {},
                    "childElements": ["Core JAVA2"],
                    "localName": "name",
                    "qName": "name",
                    "uri": "http://test.org/books"
                },
                "\n\t"
            ],
            "localName": "book",
            "qName": "book",
            "uri": "http://test.org/books"
        },
        "\n"
    ],
    "localName": "books",
    "qName": "books",
    "uri": "http://test.org/books"
} 

参考于: http://www.iteye.com/topic/402083

 

posted @ 2016-03-18 11:51  七夏之  阅读(1128)  评论(0编辑  收藏  举报