看到这个题目是不是大部分人都不屑一顾,的确基本上每个java程序猿都写过json工具类,也有很多人都使用json-lib.jar封装过类似的功能,但是我这里使用了正则来支持xml与json的互转,减少了jar包的引入。基本上满足了需求。当然如果你需要更强大的功能,还是最好使用json-lib来实现。
主要看一下工具类中的转换json和转换成xml的方法吧。
具体就不多说了,我是采用的笨方法,多次使用正则进行替换的。比较好的一点儿是支持xml元素属性。如果xml节点有属性会使用 @attributes:{属性列表} 进行格式化处理。如果有属性只有一个值,那值要采用@value:"值"进行格式化。代码如下:
/**
* 格式化为json格式
*
* @param result
* @return
*/
public static String fmt2Json(String result){
if(validate(result)){
return result;
}
result = result.replaceAll(">\\s*<", "><").replaceAll("<\\?([^>|^\\?]*)\\?>", "");
String json = result;
Matcher matcher = Pattern.compile("<([^>|^/]*)>").matcher(result);
while(matcher.find()){
for (int i = 0; i < matcher.groupCount(); i++) {
String s = matcher.group(i+1);
json = json.replaceAll("<"+s+">([^<|^\"]*)"+s+">", "\""+s+"\":\"$1\",");
}
}
json = "{"+json.replaceAll(",?([^<]*)>", "},").replaceAll("<([^<]*)>", "\"$1\":{")+"}";
json =json.replaceAll(",}","}").replaceAll("(\\s*\\w*)=\"(\\w*)\"\\s*\"?", "\"$1\":\"$2\",")
.replaceAll("\\s+([^{]*),:" , ":{\"@attributes\":{\"$1},").replace("},{", "},")
.replaceAll("},([^}|^\"]*)}", "},\"@value\":\"$1\"}");
return json;
}
发现http://www.bejson.com/xml2json/这个网站采用js比较简单,js居然用eval(json)就直接转化为树形对象了。然后就处理简单了。但是用java来模拟还是有点困难,本人也是从内部开始处理,一步一步的往外解析。然后最终简单实现了。当然还是有许多bug吧。刚测试了一下,居然不支持数组的转换。有时间再改改吧。
/**
* 格式化为xml格式
*
* @param json
* @return
*/
public static String fmt2Xml(String json){
return fmt2Xml(json, "root");
}
/**
* 格式化为xml格式
*
* @param json
* @param rootEle
* @return
*/
public static String fmt2Xml(String json, String rootEle){
if(!validate(json)){
return fmt2Xml(fmt2Json(json),rootEle);
}
rootEle = rootEle.replaceAll("\\W", "");
rootEle = StringsUtil.isNullOrEmpty(rootEle)? "root": rootEle;
// return json.replaceAll("\"(\\w*)\":\"?([^\",}]*)\"?,?","<$1>$2$1>").replaceAll("\\{([^\\}]*)\\}", "<"+rootEle+">$1"+""+rootEle+">");
//去掉@attributes和@value
Pattern pattern = Pattern.compile("\"@attributes\":\\{([^}]*)}");
Matcher matcher = pattern.matcher(json);
int t =0;
while(matcher.find()){
t++;
String s = "";
for (int i = 0; i < matcher.groupCount(); i++) {
s = matcher.group(i+1);
s = s.replaceAll("\"(\\w*)\":\"([^\"]*)\",?", " $1=$2");
}
json = json.replaceAll("[^,]\"(\\w*)\":\\{\"@attributes\":\\{[^}]*},?","{\"$1"+s+"\":{");
//matcher = pattern.matcher(json);
}
json = json.replaceAll("\\{\"@value\":\"([^\"]*)\"}", "\"$1\"");
//处理嵌套
json = json.replaceAll("\"([\\w|\\s|=]*)\":\"([^\",{}]+)\",?", "<$1>$2$1>");
pattern = Pattern.compile("\"(\\w*)\":\\{([^{}]*)},?");
while(pattern.matcher(json).find()){
json = pattern.matcher(json).replaceAll("<$1>$2$1>");
}
pattern = Pattern.compile("\"([\\w|\\s|=]*)\":([^}\"]*)},?");
while(pattern.matcher(json).find()){
json = pattern.matcher(json).replaceAll("<$1>$2$1>");
}
json = json.replaceAll("(\\w*)=(\\w*)", "$1=\"$2\"").replaceAll("/(\\w*)\\s[\\w*)=\"\\w*\"\\s?]*", "/$1").replaceAll("[{|}]", "");
json = "<"+rootEle+">"+json+""+rootEle+">";
return json;
}
来一个main方法测试测试吧:
public static void main(String[] args) {
String str = ""
+ "201 "
+ "201 APP被用户自己禁用 "
+ "201 APP被用户自己禁用 "
+ ""
+ " 201 APP被用户自己禁用 "
+ ""
+ "APP被用户自己禁用,请在控制台解禁 "
+ "201 APP被用户自己禁用 "
+ " ";
String json = fmt2Json(str);
String xml = fmt2Xml(json);
System.out.println("xml转化为json:" + json);
System.out.println("json转化为xml:" + xml);
}
测试结果如下:
xml转化为json:{"Response":{"@attributes":{"a":"123","b":"000"},"status":{"@attributes":{"c":"123","d":"000"},"@value":"201"},"A":{"status1":"201","message1":"APP被用户自己禁用"},"A2":{"status1":"201","message1":"APP被用户自己禁用"},"B":{"BB":{"status1":"201","message1":"APP被用户自己禁用"}},"message":"APP被用户自己禁用,请在控制台解禁","C":{"status1":"201","message1":"APP被用户自己禁用"}}}
json转化为xml:201 201 APP被用户自己禁用 201 APP被用户自己禁用 201 APP被用户自己禁用 APP被用户自己禁用,请在控制台解禁 201 APP被用户自己禁用
可以自行测试,然后到http://www.bejson.com/index.html 和 http://www.bejson.com/otherformat/xml/ 来检测结果中的json格式和xml格式。
工具类包代码已分享到github上:https://github.com/Arronlong/commonutils
当前工具类代码(可能博文中的代码略有出入):https://github.com/Arronlong/commonutils/tree/master/src/main/java/com/arronlong/common/util/string