【转】将XML转换为JSON (SAX解析实例)下面是一个将XML转换为JSON的示例, 通过SAX来解析XML,从而生成相应的JS
【转】将XML转换为JSON (SAX解析实例)
下面是一个将XML转换为JSON的示例,
通过SAX来解析XML,从而生成相应的JSON字符串
自我感觉还算是一个比较通用的 API ,主要包含3个类
1, ToJsonSAXHandler 类 继承了 DefaultHandler 类,在解析
XML的过程中负责处理 SAX 事件。代码如下:
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();}@Overridepublic void startDocument() throws SAXException {/* * 开始解析XML文档时 设定一些解析状态 * 设置isProcessing为true,表示XML正在被解析 * 设置justProcessStartElement为true,表示刚刚没有处理过 startElement事件 */isProcessing = true;justProcessStartElement = true;//清空 jsonStringBuilder 中的字符this.jsonStringBuilder.delete(0, this.jsonStringBuilder.length());}@Overridepublic void endDocument() throws SAXException {isProcessing = false;}@Overridepublic 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');}@Overridepublic void endElement(String uri,String localName,String qName)throws SAXException {justProcessStartElement = false;jsonStringBuilder.append("]}").append('\n');}@Overridepublic void characters(char[] ch, int begin, int length) throws SAXException {/* * 是否刚刚处理完一个startElement事件 * 如果是 则表示这个元素是父元素的第一个元素 。 * 如果不是 则表示刚刚处理完一个endElement事件,即这个元素不是父元素的第一个元素 */if(!justProcessStartElement){jsonStringBuilder.append(',');}elsejustProcessStartElement = 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");elsereturn jsonStringBuilder.toString();}}2,XMLToJSONException 是一个异常类(封装在转换过程中可能产生的异常),代码如下:
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字符串的工具类
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 解析器 ,并设置这个解析器的内容事件处理器 和 错误事件处理器 为 handlerXMLReader 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字符串):
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 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
原版主望谅解,新人不知道怎么做
