您的位置:首页 > Web前端 > JavaScript

使用sax将xml文件转成json

2012-02-14 22:56 246 查看
SAX是解析XML文档是一种“基于事件的模型”。基于SAX的解析器在处理文档时,会生成名为“事件”的通知信息。软件程序可“侦听”这些事件,以便从文档获取数据。处理大型XML文档时,SAX的解析器通常比基于DOM的解析器更有效,尤其重要的是,基于SAX的解析器不会将整个XML文档载入内存。SAX只解析一次,是顺序解析的。所以SAX速度更快,而且更省内存。

将xml文件转成json格式的,建立二个类,Xml2JsonHandler 用来解析xml文件,SaxJSON用来存放json同时运行。

首先,说明一下SAX工作流程:

第一步建立sax解析工厂:SAXParserFactory spf = SAXParserFactory.newInstance();

第二步建立sax解析对象:SAXParser parser = spf.newSAXParser();

第三部指定解析xml文件,解析:parser.parse(new File("D://1.xml"), new XmlToJson());

当读到第一个xml的“<”符号就会调用public void startDocument() 函数,而且只调用一次,当读到节点时则调用public void startElement(String url, String localName, String qName, Attributes attributes ) 函数,其中localName,qName时节点名称,attributes 时节点属性名称和节点属性的值。attributes.getQName(i)获得节点属性名称 ,attributes.getValue(i)获得节点属性的值。public void characters(char[] ch, int offset, int length)去读节点值,注意是所有的节点。当读到结束节点时调用public void endElement(String url, String localName, String qName),文档解析结束调用public void endDocument()。

类Xml2JsonHandler:

package com.xml.sax;

import java.util.HashMap;

import java.util.Map;

import org.xml.sax.Attributes;

import org.xml.sax.SAXException;

import org.xml.sax.helpers.DefaultHandler;

public class Xml2JsonHandler extends DefaultHandler{

private SaxJSON saxJson; //存放json的类

private String currentKey = ""; //当前xml的节点路线 如读到<book><y></y></book> <y> 为book.y

//解析完一个文档用来清空

public void clear(){

this.saxJson = null;

this.currentKey = "";

this.saxJson = new SaxJSON();

}

public Xml2JsonHandler(){

this.saxJson = new SaxJSON();

}

public Map getResult(){

return this.saxJson.getResult();

}

//解析文档开始

public void startDocument() {

this.saxJson.startDoc();

}

//当遇到开始节点时调用

public void startElement(String url, String localName, String qName,

Attributes attributes ) throws SAXException {

if (currentKey != null && !currentKey.equals("")) {

currentKey = currentKey + ".";

}

currentKey = currentKey + qName; //记录当前节点路径

for (int i = 0; i < attributes.getLength(); i++) {

if (attributes.getQName(i).equals("scheme")) { // 获取节点属性名称,

Map map = new HashMap();

map.put("@scheme", attributes.getValue(i)); //将节点属性名称前加@

this.saxJson.startEl(currentKey, map); // 调用saxJson的开始建json

}

}

}

public void characters(char[] ch, int offset, int length) {

// this.saxJson.characters("");

String value = new String(ch, offset, length); // 获取节点数据

value = value.replace("\n", ""); //为了去掉空格,制表符,换行等。

value = value.replace("\t", "");

value = value.replace(" ", "");

Map map = new HashMap();

map.put("#text", value);

if (length != 1 && !value.equals("")) {

this.saxJson.characters(currentKey, map); //调用saxJson的存放数据

}

}

public void endElement(String url, String localName, String qName) {

if (currentKey.lastIndexOf(".") != -1) {

currentKey = currentKey.substring(0, currentKey.lastIndexOf(qName)-1); // 去掉当前结束节点名称

}

this.saxJson.endEl();

}

// 文档结束时调用

public void endDocument() {

this.saxJson.endDoc();

Map map = this.saxJson.getResult();

System.out.println("----result----"+map);

this.clear();

}

}

类SaxJSON:

package com.xml.sax;

import java.util.ArrayList;

import java.util.HashMap;

import java.util.List;

import java.util.Map;

public class SaxJSON {

private Map map; // 存放整个xml的json

// map中存放的当前json的父节点json 如 {"a":{"b":{"#text":"c"}} 当"c"sonMap为{"b":{}}

private Map sonMap;

private String str; //@全路径名

public SaxJSON() {

}

public void startDoc() {

this.map = new HashMap();

this.sonMap = new HashMap();

this.str = "";

}

public void endDoc() {

}

public void startEl(String currentKey, Map value) {

String[] arr = currentKey.split("\\."); // 用来处理节点属性的

this.setMap(arr, value);

str = currentKey;

}

public void endEl() {

}

public void characters(String currentKey, Map value) { // 处理节点的值

String[] arr = currentKey.split("\\.");

this.setMap(arr, value);

str = "";

}

public Map getResult() {

return map;

}

/**

*

* @param arr

* arr 是一个深度的值 所有key的集合, sonMap 记录上次存放map

* @param value

*/

private void setMap(String[] arr, Object value) {

if (str != null && !str.equals("")) { // 判断有没有节点属性

String[] s = str.split("\\.");

Map m = map;

for (int i = 0; i < s.length; i++) { // 获取当前路径下的子map

m = (Map) m.get(s[i]);

}

List list = new ArrayList(); // 将节点属性 和当前的值放在一个数组存放

list.add(value);

list.add(m);

value = list;

for (int i = s.length - 1; i >=0 ; i--) {

value = maps(s[i],value); //从底层向外出建map

}

map.putAll((Map)value); //将当前map放入大map中

return;

}

for (int i = 0; i < arr.length; i++) { // 没有节点属性名称

if (map.get(arr[i]) == null) {

for (int j = arr.length - 1; j > i; j--) {

value = maps(arr[j], value); //从底层向外出建map

}

if (i == 0) { // 当前map 在大map中没有重复key值

map.put(arr[i], value); //直接放入

} else {

Map sonMap = (Map) map.get(arr[i - 1]); // 用,获取最底层sonmap;

sonMap.putAll((Map) value); //将其放入

for (int j = i - 1; j >= 0; j--) {

sonMap = maps(arr[j], sonMap);

if (j == 0) {

map.putAll(sonMap);

}

}

}

return;

}

}

}

private Map maps(Object key, Object ma) {

Map m = new HashMap();

m.put(key, ma);

return m;

}

}

测试类:

package com.xml.sax;

import java.io.File;

import java.io.IOException;

import java.util.HashMap;

import java.util.Map;

import javax.xml.parsers.ParserConfigurationException;

import javax.xml.parsers.SAXParser;

import javax.xml.parsers.SAXParserFactory;

import org.xml.sax.SAXException;

public class TestMain {

public static void main(String[] args) throws ParserConfigurationException, SAXException, IOException {

SAXParserFactory spf = SAXParserFactory.newInstance();

SAXParser parser = spf.newSAXParser();

parser.parse(new File("D://2.xml"),new Xml2JsonHandler());

}

}

xml 文件:

<?xml version="1.0" encoding="UTF-8"?>

<people>

<person>

<name scheme="213213">zhangsan</name>

<tel>5128</tel>

<email>txq512@sina.com</email>

</person>

</people>

结果为:

----result----{people={person={name=[{#text=zhangsan}, {@scheme=213213}]}, email={#text=txq512@sina.com}, tel={#text=5128}}}
本文出自 “清风” 博客,请务必保留此出处http://zhangxu2713.blog.51cto.com/3806781/780015
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: