`

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

 
阅读更多

本文出自:http://www.iteye.com/topic/402083

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

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

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

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

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

Java代码 收藏代码
  1. packageorg.yjf.xmlToJson;
  2. importorg.xml.sax.Attributes;
  3. importorg.xml.sax.SAXException;
  4. importorg.xml.sax.helpers.DefaultHandler;
  5. publicclassToJsonSAXHandlerextendsDefaultHandler{
  6. //jsonStringBuilder保存解析XML时生成的json字符串
  7. privateStringBuilderjsonStringBuilder;
  8. /*
  9. *isProcessing表示是否正在解析一个XML
  10. *startDocument事件发生时设置isProcessing=true
  11. *startDocument事件发生时设置isProcessing=false
  12. */
  13. privatebooleanisProcessing;
  14. /*
  15. *justProcessStartElement表示是否刚刚处理完一个startElement事件
  16. *引入这个标记的作用是为了判断什么时候输出逗号
  17. */
  18. privatebooleanjustProcessStartElement;
  19. publicToJsonSAXHandler(){
  20. jsonStringBuilder=newStringBuilder();
  21. }
  22. @Override
  23. publicvoidstartDocument()throwsSAXException{
  24. /*
  25. *开始解析XML文档时设定一些解析状态
  26. *设置isProcessing为true,表示XML正在被解析
  27. *设置justProcessStartElement为true,表示刚刚没有处理过startElement事件
  28. */
  29. isProcessing=true;
  30. justProcessStartElement=true;
  31. //清空jsonStringBuilder中的字符
  32. this.jsonStringBuilder.delete(0,this.jsonStringBuilder.length());
  33. }
  34. @Override
  35. publicvoidendDocument()throwsSAXException{
  36. isProcessing=false;
  37. }
  38. @Override
  39. publicvoidstartElement(Stringuri,StringlocalName,StringqName,
  40. Attributesattrs)throwsSAXException{
  41. /*
  42. *是否刚刚处理完一个startElement事件
  43. *如果是则表示这个元素是父元素的第一个元素。
  44. *如果不是则表示刚刚处理完一个endElement事件,即这个元素不是父元素的第一个元素
  45. */
  46. if(!justProcessStartElement){
  47. jsonStringBuilder.append(',');
  48. justProcessStartElement=true;
  49. }
  50. jsonStringBuilder.append("{");
  51. jsonStringBuilder.append("localName:").append('\"').append(localName).append('\"').append(',');
  52. jsonStringBuilder.append("uri:").append('\"').append(uri).append('\"').append(',');
  53. jsonStringBuilder.append("qName:").append('\"').append(qName).append('\"').append(',');
  54. //将解析出来的元素属性添加到JSON字符串中
  55. jsonStringBuilder.append("attrs:{");
  56. if(attrs.getLength()>0){
  57. jsonStringBuilder.append(attrs.getLocalName(0)).append(":")
  58. .append(attrs.getValue(0));
  59. for(inti=1;i<attrs.getLength();i++){
  60. jsonStringBuilder.append(',').append(attrs.getLocalName(i)).append(":")
  61. .append(attrs.getValue(i));
  62. }
  63. }
  64. jsonStringBuilder.append("},");
  65. //将解析出来的元素的子元素列表添加到JSON字符串中
  66. jsonStringBuilder.append("childElements:[").append('\n');
  67. }
  68. @Override
  69. publicvoidendElement(Stringuri,StringlocalName,StringqName)
  70. throwsSAXException{
  71. justProcessStartElement=false;
  72. jsonStringBuilder.append("]}").append('\n');
  73. }
  74. @Override
  75. publicvoidcharacters(char[]ch,intbegin,intlength)
  76. throwsSAXException{
  77. /*
  78. *是否刚刚处理完一个startElement事件
  79. *如果是则表示这个元素是父元素的第一个元素。
  80. *如果不是则表示刚刚处理完一个endElement事件,即这个元素不是父元素的第一个元素
  81. */
  82. if(!justProcessStartElement){
  83. jsonStringBuilder.append(',');
  84. }else
  85. justProcessStartElement=false;
  86. jsonStringBuilder.append('\"');
  87. for(inti=begin;i<begin+length;i++){
  88. switch(ch[i]){
  89. case'\'':jsonStringBuilder.append("\\'");break;
  90. case'\"':jsonStringBuilder.append("\\\"");break;
  91. case'\n':jsonStringBuilder.append("\\n");break;
  92. case'\t':jsonStringBuilder.append("\\t");break;
  93. case'\r':jsonStringBuilder.append("\\r");break;
  94. default:jsonStringBuilder.append(ch[i]);break;
  95. }
  96. }
  97. jsonStringBuilder.append('\"').append('\n');
  98. }
  99. publicStringgetJsonString()throwsXMLToJSONException{
  100. if(this.isProcessing)
  101. thrownewXMLToJSONException("getJsonStringbeforeresolutionisfinished");
  102. else
  103. returnjsonStringBuilder.toString();
  104. }
  105. }


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

Java代码 收藏代码
  1. packageorg.yjf.xmlToJson;
  2. publicclassXMLToJSONExceptionextendsException{
  3. privatestaticfinallongserialVersionUID=1L;
  4. publicXMLToJSONException(){}
  5. publicXMLToJSONException(Stringmessage){
  6. super(message);
  7. }
  8. }

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

Java代码 收藏代码
  1. packageorg.yjf.xmlToJson;
  2. importjava.io.File;
  3. importjava.io.FileInputStream;
  4. importjava.io.IOException;
  5. importjava.io.StringReader;
  6. importorg.xml.sax.InputSource;
  7. importorg.xml.sax.SAXException;
  8. importorg.xml.sax.XMLReader;
  9. importorg.xml.sax.helpers.XMLReaderFactory;
  10. publicclassXMLToJSON{
  11. publicstaticStringconvert(StringxmlStr)throwsSAXException,
  12. IOException,XMLToJSONException{
  13. returnconvert(newInputSource(newStringReader(xmlStr)));
  14. }
  15. publicstaticStringconvert(Filefile)throwsSAXException,
  16. IOException,XMLToJSONException{
  17. returnconvert(newInputSource(newFileInputStream(file)));
  18. }
  19. publicstaticStringconvert(InputSourceinputSource)throwsSAXException,
  20. IOException,XMLToJSONException{
  21. ToJsonSAXHandlerhandler=newToJsonSAXHandler();
  22. //创建一个SAX解析器,并设置这个解析器的内容事件处理器和错误事件处理器为handler
  23. XMLReaderreader=XMLReaderFactory.createXMLReader();
  24. reader.setContentHandler(handler);
  25. reader.setErrorHandler(handler);
  26. //用SAX解析器解析XML输入源
  27. reader.parse(inputSource);
  28. //返回ToJsonSAXHandler中保存的json字符串
  29. returnhandler.getJsonString();
  30. }
  31. }

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

Java代码 收藏代码
  1. packagetest;
  2. importjava.io.File;
  3. importjava.io.IOException;
  4. importorg.json.JSONException;
  5. importorg.json.JSONObject;
  6. importorg.xml.sax.SAXException;
  7. importorg.yjf.xmlToJson.XMLToJSON;
  8. importorg.yjf.xmlToJson.XMLToJSONException;
  9. publicclassTest_1{
  10. publicstaticvoidmain(String[]args)throwsJSONException,
  11. SAXException,IOException,XMLToJSONException{
  12. StringjsonStr=XMLToJSON.convert(newFile("books.xml"));
  13. /*
  14. *JSONObject是一个JSON对象的java实现
  15. *可以通过用一个有效的JSON字符串来构造JSON对象
  16. *下面的两行代码通过转换而来的JSON字符串构造了一个JSON对象,
  17. *并且打印出了这个JSON对象的带有缩进的字符串表示
  18. */
  19. JSONObjectjsonObj=newJSONObject(jsonStr);
  20. System.out.println(jsonObj.toString(2));
  21. }
  22. }

books.xml 的内容如下:

Xml代码 收藏代码
  1. <?xmlversion="1.0"encoding="utf-8"?>
  2. <bookscount="2"xmlns="http://test.org/books">
  3. <bookid="1"page="1000">
  4. <name>ThinkinginJAVA</name>
  5. </book>
  6. <bookid="2"page="800">
  7. <name>CoreJAVA2</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"
}


发表时间:2009-06-05 最后修改:2009-06-05

用这种方式 生成 的JSON 对象,比如:

Java代码 收藏代码
  1. <span><spanstyle="color:#0000ff;font-size:small;">varbooks={
  2. "attrs":{"count":2},
  3. "childElements":[
  4. "\n\t",
  5. {
  6. "attrs":{
  7. "id":1,
  8. "page":1000
  9. },
  10. "childElements":[
  11. "\n\t\t",
  12. {
  13. "attrs":{},
  14. "childElements":["ThinkinginJAVA"],
  15. "localName":"name",
  16. "qName":"name",
  17. "uri":"http://test.org/books"
  18. },
  19. "\n\t"
  20. ],
  21. "localName":"book",
  22. "qName":"book",
  23. "uri":"http://test.org/books"
  24. },
  25. "\n\t",
  26. {
  27. "attrs":{
  28. "id":2,
  29. "page":800
  30. },
  31. "childElements":[
  32. "\n\t\t",
  33. {
  34. "attrs":{},
  35. "childElements":["CoreJAVA2"],
  36. "localName":"name",
  37. "qName":"name",
  38. "uri":"http://test.org/books"
  39. },
  40. "\n\t"
  41. ],
  42. "localName":"book",
  43. "qName":"book",
  44. "uri":"http://test.org/books"
  45. },
  46. "\n"
  47. ],
  48. "localName":"books",
  49. "qName":"books",
  50. "uri":"http://test.org/books"
  51. }</span></span>

如果用JS访问感觉还是不太方便,如果要访问“Thinking in java”这个文本,

需要 用这个表达式 books.childElements[2].childElements[1].childElements[0]

这样看起来不是很直观 ,感觉要是用这个表达式 books.book[0].name就更直观了


分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics