笔者电话Google Calendar APIs的GetColors方法,其中(有关详细信息Google Calendar API已经Google API看到我的博文介绍的其余部分,目前,我们只取Google Calendar API对于返回的样品结果)。JSON数据恢复。作为键(key)的数据;可是由于我们在企业应用集成中。有时候须要把JSON数据转换成XML数据;那么这个时候,JSON数据中的键(key)映射到XML数据中将成为XML数据的节点名字(Node Name),假设JSON中的键(key)是数字的话,映射到XML数据的时候就会出错,由于XML规范中不支持把纯粹的数字作为XML数据的节点名字。这样的情况下。我们就须要在对JSON数据转换成XML数据之间,进行一下处理。
以Google 日历(Calendar) API中的获取颜色(Get Color)的数据为样例,请见以下的数据。
Calendar键(key)中的值,是一个包括多个对象的对象;每一个对象的键(key)是一个数字。并且数字呈现递增的趋势;同理Event键(key)中的值也有相同的特征;假设把这种数据转换成XML的数据的话。转换将不会成功。
{
"kind": "calendar#colors",
"updated": "2012-02-14T00:00:00.000Z",
"calendar": {
"1": {
"background": "#ac725e",
"foreground": "#1d1d1d"
},
"2": {
"background": "#d06b64",
"foreground": "#1d1d1d"
},
"3": {
"background": "#f83a22",
"foreground": "#1d1d1d"
}
},
"event": {
"1": {
"background": "#a4bdfc",
"foreground": "#1d1d1d"
},
"2": {
"background": "#7ae7bf",
"foreground": "#1d1d1d"
}
}
}
比方,我们把上面的数据。在一个在线的JSON转XML的站点上进行转换,http://www.freeformatter.com/json-to-xml-converter.html。在这个在线工具里面将会提示以下的错误信息:
那么解决的办法是什么呢?解决的办法就是把上面的带有数字的键(key)值对集合。变成一个没有数字的键(key)的数组。如以下的格式。
{
"kind": "calendar#colors",
"updated": "2012-02-14T00:00:00.000Z",
"calendar": [{
"background": "#ac725e",
"foreground": "#1d1d1d"
},
{
"background": "#d06b64",
"foreground": "#1d1d1d"
},
{
"background": "#f83a22",
"foreground": "#1d1d1d"
}
]
},
"event": [{
"background": "#a4bdfc",
"foreground": "#1d1d1d"
},
{
"background": "#7ae7bf",
"foreground": "#1d1d1d"
}
]
}
}
转换后的XML的数据例如以下。
<? xml version="1.0" encoding="UTF-8"? >
<root>
<calendar>
<element>
<background>#ac725e</background>
<foreground>#1d1d1d</foreground>
</element>
<element>
<background>#d06b64</background>
<foreground>#1d1d1d</foreground>
</element>
<element>
<background>#f83a22</background>
<foreground>#1d1d1d</foreground>
</element>
</calendar>
<kind>calendar#colors</kind>
<updated>2012-02-14T00:00:00.000Z</updated>
</root>
那么问题来,假设用代码自己主动来实现转换且不引入不论什么的除JDK自带的API之外的其它的jar包呢?详细算法。请见以下的代码。
1. NumberKeyPosition Java Bean: 用来存储数字键(key)在JSON字符串中出现的開始位置。结束位置,以及是否是第一个数字键(key),是否是最后一个数字数字键(key),比方上面的中以下的数据,是calendar的第一个,所以isFirstOne的值为True。
"1": {
"background": "#ac725e",
"foreground": "#1d1d1d"
}
public class NumberKeyPosition { private int startPos;
private int endPos;
private boolean isFirstOne=false;
private boolean isLastOne=false; public int getStartPos() {
return startPos;
} public void setStartPos(int startPos) {
this.startPos = startPos;
} public int getEndPos() {
return endPos;
} public void setEndPos(int endPos) {
this.endPos = endPos;
} public boolean isFirstOne() {
return isFirstOne;
} public void setFirstOne(boolean isFirstOne) {
this.isFirstOne = isFirstOne;
} public boolean isLastOne() {
return isLastOne;
} public void setLastOne(boolean isLastOne) {
this.isLastOne = isLastOne;
}
}
2. CovertNumberKeyAsArrayUtil 类:这个类就是运行上面处理JSON数据的详细的运行算法的类了。
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class CovertNumberKeyAsArrayUtil {
private String jsonString;
public void setJsonString(String jsonString) {
this.jsonString = jsonString;
}
public CovertNumberKeyAsArrayUtil(){ }
public CovertNumberKeyAsArrayUtil(String jsonString){
this.jsonString=jsonString;
} public String readFileAsString(String fileName){
InputStream ins=this.getClass().getResourceAsStream(fileName);
StringBuffer sBuffer=new StringBuffer();
BufferedReader bufferedReader=new BufferedReader(new InputStreamReader(ins));
String lineString="";
try {
while((lineString=bufferedReader.readLine())!=null){
sBuffer.append(lineString);
}
} catch (IOException e) {
e.printStackTrace();
}
//System.out.println(sBuffer.toString());
return sBuffer.toString();
}
/**
* getNumberKeyPositions
* @param jsonString
* @return
*/
private List<NumberKeyPosition> getNumberKeyPositions(){
List<NumberKeyPosition> lsNumberKeyPosition=new ArrayList<NumberKeyPosition>();
String expression="\"\\d*\":";
Pattern p = Pattern.compile(expression);
Matcher m = p.matcher(jsonString);
StringBuffer sb = new StringBuffer();
int prevIndex=0;
while (m.find()) {
NumberKeyPosition numberKeyPosition=new NumberKeyPosition();
String matchString=m.group();
int currentIndex=Integer.parseInt(matchString.trim().replace("\"", "").replace(":", ""));
numberKeyPosition.setStartPos(m.start());
numberKeyPosition.setEndPos(m.end());
//System.out.println("Start Pos:"+m.start());
//System.out.println("End Pos:"+m.end());
if(currentIndex==1){
numberKeyPosition.setFirstOne(true);
if(prevIndex==1){
if(lsNumberKeyPosition.size()>0){
lsNumberKeyPosition.get(lsNumberKeyPosition.size()-1).setLastOne(true);
}
}else{
if(prevIndex>1){
lsNumberKeyPosition.get(lsNumberKeyPosition.size()-1).setLastOne(true);
}
} }else{
numberKeyPosition.setFirstOne(false);
numberKeyPosition.setLastOne(false);
}
prevIndex=currentIndex;
lsNumberKeyPosition.add(numberKeyPosition);
}
if(lsNumberKeyPosition!=null&&lsNumberKeyPosition.size()>0){
lsNumberKeyPosition.get(lsNumberKeyPosition.size()-1).setLastOne(true);
}
return lsNumberKeyPosition;
}
/**
*
* @param endOfLastPositionString
* @return
* @Test data: { "background": "#f83a22", "foreground": "#1d1d1d" } }, "event": {
* { "background": "#f83a22", "foreground": "#1d1d1d" } }, "event": {
*/
public String addBracket4EndPostion(String endOfLastPositionString){
StringBuffer sBuffer=new StringBuffer();
int leftBracketCount=0;
int leftBracketCountFirstIndex=endOfLastPositionString.indexOf('{');
boolean isAddBracketSucc=false;
boolean isRemovedLaterBrace=false;
for(int i=0;i<endOfLastPositionString.length();i++){
if(endOfLastPositionString.charAt(i)=='{'){
leftBracketCount++;
} else if(endOfLastPositionString.charAt(i)=='}'){
leftBracketCount--;
}
sBuffer.append(endOfLastPositionString.charAt(i));
if(leftBracketCount==0&&i>leftBracketCountFirstIndex&&!isAddBracketSucc){
sBuffer.append(']');
isAddBracketSucc=true;
continue;
}
if(isAddBracketSucc&&!isRemovedLaterBrace&&endOfLastPositionString.charAt(i)=='}'){
int lenStringBuffer=sBuffer.length();
sBuffer=new StringBuffer(sBuffer.substring(0, lenStringBuffer-1));
isRemovedLaterBrace=true;
} }
return sBuffer.toString();
} private String trimRightBrace(String tmpString) {
String trimRightBraceString = "";
if (tmpString != null) {
tmpString=tmpString.trim();
int len = tmpString.length();
if (len > 1 && tmpString.endsWith("{")) {
trimRightBraceString = tmpString.substring(0, len - 2);
}
}
return trimRightBraceString;
}
/**
* getRemovedNumberKeyJSONString
* @return
*/
public String getRemovedNumberKeyJSONString(){
//String removedNumberKeyJSONString=null;
List<NumberKeyPosition> lsNumberKeyPosition=this.getNumberKeyPositions();
StringBuffer sbBuffer=new StringBuffer();
if(lsNumberKeyPosition!=null&&lsNumberKeyPosition.size()>0){
for(int i=0;i<lsNumberKeyPosition.size();i++){
NumberKeyPosition currentnumberKeyPosition=lsNumberKeyPosition.get(i);
if(i==0){
String tmpString=jsonString.substring(0, currentnumberKeyPosition.getStartPos()).trim();
sbBuffer.append(trimRightBrace(tmpString));
sbBuffer.append("[");
}else{
NumberKeyPosition preNumberKeyPosition=lsNumberKeyPosition.get(i-1);
if(currentnumberKeyPosition.isFirstOne()){
sbBuffer.append("[");
}else{
if(currentnumberKeyPosition.isLastOne()){
sbBuffer.append(jsonString.substring(preNumberKeyPosition.getEndPos(), currentnumberKeyPosition.getStartPos()));
if(i<lsNumberKeyPosition.size()-1){
NumberKeyPosition nextNumberKeyPosition=lsNumberKeyPosition.get(i+1);
String endOfLastPositionString=jsonString.substring(currentnumberKeyPosition.getEndPos(),nextNumberKeyPosition.getStartPos()).trim();
sbBuffer.append(addBracket4EndPostion(trimRightBrace(endOfLastPositionString)));
}else{
String endOfLastPositionString=jsonString.substring(currentnumberKeyPosition.getEndPos(),jsonString.length());
sbBuffer.append(addBracket4EndPostion(endOfLastPositionString));
}
}else{
sbBuffer.append(jsonString.substring(preNumberKeyPosition.getEndPos(), currentnumberKeyPosition.getStartPos()));
}
}
}
}
}
return sbBuffer.toString();
}
public static void main(String[] args) {
CovertNumberKeyAsArrayUtil covertNumberKeyAsArrayUtil=new CovertNumberKeyAsArrayUtil();
covertNumberKeyAsArrayUtil.setJsonString(covertNumberKeyAsArrayUtil.readFileAsString("jsonColorNumber.json"));
String removedNumberKeyJSONString=covertNumberKeyAsArrayUtil.getRemovedNumberKeyJSONString();
System.out.println(removedNumberKeyJSONString);
} }
版权声明:本文博客原创文章。博客,未经同意,不得转载。