将XML转换为JSON的示例

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

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

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

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

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

Java代码 
  1. package org.yjf.xmlToJson; 
  2.  
  3. import org.xml.sax.Attributes; 
  4. import org.xml.sax.SAXException; 
  5. import org.xml.sax.helpers.DefaultHandler; 
  6.  
  7. public class ToJsonSAXHandler extends DefaultHandler { 
  8.      
  9.     //jsonStringBuilder 保存解析XML时生成的json字符串 
  10.     private StringBuilder jsonStringBuilder ; 
  11.      
  12.     /*
  13.      *  isProcessing 表示 是否正在解析一个XML
  14.      *      startDocument 事件发生时设置 isProcessing = true
  15. * startDocument 事件发生时设置 isProcessing = false
  16.      */ 
  17.     private boolean isProcessing; 
  18.      
  19.     /*
  20.      *  justProcessStartElement 表示 是否刚刚处理完一个 startElement事件
  21.      *  引入这个标记的作用是为了判断什么时候输出逗号
  22.      */ 
  23.     private boolean justProcessStartElement; 
  24.      
  25.     public ToJsonSAXHandler(){ 
  26.         jsonStringBuilder = new StringBuilder(); 
  27.     } 
  28.      
  29.     @Override 
  30.     public void startDocument() throws SAXException { 
  31.         /*
  32.          * 开始解析XML文档时 设定一些解析状态
  33.          *     设置isProcessing为true,表示XML正在被解析
  34.          *     设置justProcessStartElement为true,表示刚刚没有处理过 startElement事件
  35.          */ 
  36.         isProcessing = true
  37.         justProcessStartElement = true
  38.         //清空 jsonStringBuilder 中的字符 
  39.         this.jsonStringBuilder.delete(0, this.jsonStringBuilder.length()); 
  40.     } 
  41.      
  42.     @Override 
  43.     public void endDocument() throws SAXException { 
  44.         isProcessing = false
  45.     } 
  46.      
  47.     @Override 
  48.     public void startElement(String uri, String localName, String qName,  
  49.             Attributes attrs) throws SAXException {  
  50.         /*
  51.          * 是否刚刚处理完一个startElement事件
  52.          *     如果是 则表示这个元素是父元素的第一个元素 。
  53.          *     如果不是 则表示刚刚处理完一个endElement事件,即这个元素不是父元素的第一个元素
  54.          */ 
  55.         if(!justProcessStartElement){ 
  56.             jsonStringBuilder.append(','); 
  57.             justProcessStartElement = true
  58.         } 
  59.         jsonStringBuilder.append("{"); 
  60.         jsonStringBuilder.append("localName:").append('\"').append(localName).append('\"').append(','); 
  61.         jsonStringBuilder.append("uri:").append('\"').append(uri).append('\"').append(','); 
  62.         jsonStringBuilder.append("qName:").append('\"').append(qName).append('\"').append(','); 
  63.         //将解析出来的元素属性添加到JSON字符串中 
  64.         jsonStringBuilder.append("attrs:{"); 
  65.         if(attrs.getLength() > 0){ 
  66.             jsonStringBuilder.append(attrs.getLocalName(0)).append(":"
  67.                 .append(attrs.getValue(0)); 
  68.             for(int i = 1 ; i < attrs.getLength() ; i++){ 
  69.                 jsonStringBuilder.append(',').append(attrs.getLocalName(i)).append(":"
  70.                     .append(attrs.getValue(i)); 
  71.             }    
  72.         } 
  73.         jsonStringBuilder.append("},"); 
  74.         //将解析出来的元素的子元素列表添加到JSON字符串中 
  75.         jsonStringBuilder.append("childElements:[").append('\n'); 
  76.     } 
  77.      
  78.     @Override 
  79.     public void endElement(String uri,String localName,String qName) 
  80.             throws SAXException { 
  81.         justProcessStartElement = false
  82.         jsonStringBuilder.append("]}").append('\n'); 
  83.     } 
  84.  
  85.     @Override 
  86.     public void characters(char[] ch, int begin, int length)  
  87.             throws SAXException { 
  88.         /*
  89.          * 是否刚刚处理完一个startElement事件
  90.          *     如果是 则表示这个元素是父元素的第一个元素 。
  91.          *     如果不是 则表示刚刚处理完一个endElement事件,即这个元素不是父元素的第一个元素
  92.          */ 
  93.         if(!justProcessStartElement){ 
  94.             jsonStringBuilder.append(','); 
  95.         }else 
  96.             justProcessStartElement = false
  97.          
  98.         jsonStringBuilder.append('\"'); 
  99.         for(int i = begin ; i < begin+length ; i++){ 
  100.             switch(ch[i]){ 
  101.                 case '\'':jsonStringBuilder.append("\\'");break
  102.                 case '\"':jsonStringBuilder.append("\\\"");break
  103.                 case '\n':jsonStringBuilder.append("\\n");break
  104.                 case '\t':jsonStringBuilder.append("\\t");break
  105.                 case '\r':jsonStringBuilder.append("\\r");break
  106.                 default:  jsonStringBuilder.append(ch[i]);break
  107.             } 
  108.         } 
  109.         jsonStringBuilder.append('\"').append('\n'); 
  110.     } 
  111.      
  112.     public String getJsonString() throws XMLToJSONException{ 
  113.         if(this.isProcessing) 
  114.             throw new XMLToJSONException("getJsonString before resolution is finished"); 
  115.         else 
  116.             return jsonStringBuilder.toString(); 
  117.     } 
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代码 复制代码 收藏代码
  1. package org.yjf.xmlToJson; 
  2.  
  3. public class XMLToJSONException extends Exception { 
  4.  
  5.     private static final long serialVersionUID = 1L; 
  6.      
  7.     public XMLToJSONException(){} 
  8.     public XMLToJSONException(String message){ 
  9.         super(message); 
  10.     } 
  11.  
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代码 复制代码 收藏代码
  1. package org.yjf.xmlToJson; 
  2.  
  3. import java.io.File; 
  4. import java.io.FileInputStream; 
  5. import java.io.IOException; 
  6. import java.io.StringReader; 
  7.  
  8. import org.xml.sax.InputSource; 
  9. import org.xml.sax.SAXException; 
  10. import org.xml.sax.XMLReader; 
  11. import org.xml.sax.helpers.XMLReaderFactory; 
  12.  
  13. public class XMLToJSON { 
  14.      
  15.     public static String convert(String xmlStr) throws SAXException, 
  16.             IOException, XMLToJSONException { 
  17.         return convert(new InputSource(new StringReader(xmlStr))); 
  18.     } 
  19.  
  20.     public static String convert(File file) throws SAXException, 
  21.             IOException, XMLToJSONException { 
  22.         return convert(new InputSource(new FileInputStream(file))); 
  23.     } 
  24.  
  25.     public static String convert(InputSource inputSource) throws SAXException, 
  26.             IOException, XMLToJSONException { 
  27.         ToJsonSAXHandler handler = new ToJsonSAXHandler(); 
  28.         //创建一个 SAX 解析器 ,并设置这个解析器的内容事件处理器 和 错误事件处理器 为 handler 
  29.         XMLReader reader = XMLReaderFactory.createXMLReader(); 
  30.         reader.setContentHandler(handler); 
  31.         reader.setErrorHandler(handler); 
  32.         //用 SAX 解析器解析XML输入源 
  33.         reader.parse(inputSource); 
  34.         //返回 ToJsonSAXHandler 中保存的 json字符串 
  35.         return handler.getJsonString(); 
  36.     } 
  37.  
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; 
  2.  
  3. import java.io.File; 
  4. import java.io.IOException; 
  5.  
  6. import org.json.JSONException; 
  7. import org.json.JSONObject; 
  8. import org.xml.sax.SAXException; 
  9. import org.yjf.xmlToJson.XMLToJSON; 
  10. import org.yjf.xmlToJson.XMLToJSONException; 
  11.  
  12. public class Test_1 { 
  13.  
  14.     public static void main(String[] args) throws JSONException,  
  15.             SAXException, IOException, XMLToJSONException{ 
  16.         String jsonStr = XMLToJSON.convert(new File("books.xml")); 
  17.         /*
  18.          * JSONObject 是一个JSON对象的java实现
  19.          * 可以通过用一个有效的JSON字符串来构造JSON对象
  20.          * 下面的两行代码通过转换而来的JSON字符串构造了一个JSON对象,
  21.          * 并且打印出了这个JSON对象的带有缩进的字符串表示
  22.          */ 
  23.         JSONObject jsonObj = new JSONObject(jsonStr); 
  24.         System.out.println(jsonObj.toString(2)); 
  25.     } 
  26.  
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"?> 
  2. <books  count="2" xmlns="http://test.org/books"> 
  3.     <book id="1" page="1000"> 
  4.         <name>Thinking in JAVA</name> 
  5.     </book> 
  6.     <book id="2" page="800"> 
  7.         <name>Core JAVA2</name> 
  8.     </book> 
  9. </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
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值