笔者电话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);
} }

版权声明:本文博客原创文章。博客,未经同意,不得转载。

如何使用Google APIs和Google应用系统集成(7)----在里面JSON兑换XML数据处理,JSON数据包括违规XML数据规范:XML节点名称不支持号码Java解的更多相关文章

  1. 怎样用Google APIs和Google的应用系统进行集成(3)----调用Google 发现(Discovery)API的RESTful服务

    说了这么多,那么首先同意我以Google Discovery RESTful服务为例,给大家演示怎样用最普通的Java代码调用Google Discovery RESTful服务. 引言: 在&quo ...

  2. 怎样用Google APIs和Google的应用系统进行集成(4)----获得Access Token以通过一些Google APIs的OAuth2认证

    在上篇文章中: "怎样用Google APIs和Google的应用系统进行集成(3)----调用发现Google APIs的RESTful的服务"一文中,我们直接用jdk的java ...

  3. 怎样用Google APIs和Google的应用系统进行集成(1)----Google APIs简介

    Google的应用系统提供了非常多的应用,比方 Google广告.Google 任务,Google 日历.Google blogger,Google Plus,Google 地图等等非常的多的应用,请 ...

  4. 怎样用Google APIs和Google的应用系统进行集成(2)----Google APIs的全部的RESTFul服务一览

    上篇文章,我提到了,Google APIs暴露了86种不同种类和版本号的API.我们能够通过在浏览器里面输入https://www.googleapis.com/discovery/v1/apis这个 ...

  5. 怎样用Google APIs和Google的应用系统进行集成(8)----怎样把Google Blogger(博客)的JSON Schema转换成XML的Schema(XSD)?

    在Google RESTFul API中,Google Blogger API(Google博客API)应该和我们的生活离得近期:由于差点儿非常多人每天都在看博客,都在写博客,都听说过博客.在前面的G ...

  6. 怎样用Google APIs和Google的应用系统进行集成(5)----怎样把Google Tasks的JSON Schema转换成XML的Schema(XSD)?

    前面说了一些Google API的介绍,可是在实际的开发其中,我们可能须要把Google RESTful API返回的JSON数据转换成XML数据输入到第三方系统,这在企业应用集成里面很的常见. 那么 ...

  7. 谷歌正式发布Google APIs Client Library for .NET

    好消息,特大好消息! 英文原文:Google API library for .NET paves the way for Google services on Windows phone 本月 17 ...

  8. Android SDK Manager Google Apis 下载

    本意是想利用google的gcm来实装android推送功能的,很遗憾, google貌似已经停止提供啥服务给国内了,或者说国内想继续使用google 服务暂时变得几乎不可能了.找了个代理来进行goo ...

  9. gRPC版本的 Google APIs

    gRPC将是未来google所有客户端的库标准(DevoxxFR), 这句话的出处: https://twitter.com/chanezon/status/585724143003402240    ...

随机推荐

  1. windows phone (19) 深入了解TextBlock

    原文:windows phone (19) 深入了解TextBlock TextBlock 一般用于显示文本的元素,我们最为经常用到的是该类的Text属性,其实显示文本有两种呈现方式,一个是设置内部文 ...

  2. 使用oracle数据库,多用户同时对一个表进行增加,删除,修改,查看等操作,会不会有影响?

    使用oracle数据库,多用户同时对一个表进行增加,删除,修改,查看等操作,会不会有影响? 1.问题:各操作间或者性能上会不会有影响? 如果有该如何解决? 多用户操作的影响主要是回锁定记录,oracl ...

  3. 重新想象 Windows 8 Store Apps (12) - 控件之 GridView 特性: 拖动项, 项尺寸可变, 分组显示

    原文:重新想象 Windows 8 Store Apps (12) - 控件之 GridView 特性: 拖动项, 项尺寸可变, 分组显示 [源码下载] 重新想象 Windows 8 Store Ap ...

  4. 程序员之---C语言细节22(函数返回指针注意事项&lt;悬空指针&gt;、查看进程能够分配的内存大小)

    主要内容:函数返回指针注意事项<悬空指针>.查看进程能够分配的内存大小 #include <stdio.h> char * favorite_fruit() { static ...

  5. testlink于smarty配置和使用

    于testlink于,采用smarty首先配置. 一般在过程化的编程中.创建一个smarty.inc.php的文件来配置Smarty的信息,其它文件引入就可以,目的是为了不改动smarty.class ...

  6. fork与vfork详解

    一.fork函数 要创建一个进程,最基本的系统调用是fork,系统调用fork用于派生一个进程,函数原型如下: pid_t fork(void)  若成功,父进程中返回子进程ID,子进程中返回0,若出 ...

  7. 【Nginx】开发一个简单的HTTP模块

    首先来分析一下HTTP模块是怎样介入Nginx的. 当master进程fork出若干个workr子进程后,每一个worker子进程都会在自己的for死循环中不断调用事件模块: for ( ;; ) { ...

  8. 同TextView在不同的显示内容

    首先,请原谅我不能命名文章.. . 我们不能准确地表达你说说什么什么,真正急着赶智商. 直接在地图上 如图所看到的显示的是两个textview 第一个实现的是,在同一个textview中给不同内容赋予 ...

  9. Java线程Dump分析工具--jstack(转)

    jstack用于打印出给定的java进程ID或core file或远程调试服务的Java堆栈信息,如果是在64位机器上,需要指定选项"-J-d64",Windows的jstack使 ...

  10. OllyDbg 使用注意事项 (十)

    OllyDbg 用笔记 (十) 參考 书:<加密与解密> 视频:小甲鱼 解密系列 视频 演示样例程序下载地址:http://pan.baidu.com/s/1kT1ce83 这个程序能够从 ...