如何使用Google APIs和Google应用系统集成(7)----在里面JSON兑换XML数据处理,JSON数据包括违规XML数据规范:XML节点名称不支持号码Java解
笔者电话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解的更多相关文章
- 怎样用Google APIs和Google的应用系统进行集成(3)----调用Google 发现(Discovery)API的RESTful服务
说了这么多,那么首先同意我以Google Discovery RESTful服务为例,给大家演示怎样用最普通的Java代码调用Google Discovery RESTful服务. 引言: 在&quo ...
- 怎样用Google APIs和Google的应用系统进行集成(4)----获得Access Token以通过一些Google APIs的OAuth2认证
在上篇文章中: "怎样用Google APIs和Google的应用系统进行集成(3)----调用发现Google APIs的RESTful的服务"一文中,我们直接用jdk的java ...
- 怎样用Google APIs和Google的应用系统进行集成(1)----Google APIs简介
Google的应用系统提供了非常多的应用,比方 Google广告.Google 任务,Google 日历.Google blogger,Google Plus,Google 地图等等非常的多的应用,请 ...
- 怎样用Google APIs和Google的应用系统进行集成(2)----Google APIs的全部的RESTFul服务一览
上篇文章,我提到了,Google APIs暴露了86种不同种类和版本号的API.我们能够通过在浏览器里面输入https://www.googleapis.com/discovery/v1/apis这个 ...
- 怎样用Google APIs和Google的应用系统进行集成(8)----怎样把Google Blogger(博客)的JSON Schema转换成XML的Schema(XSD)?
在Google RESTFul API中,Google Blogger API(Google博客API)应该和我们的生活离得近期:由于差点儿非常多人每天都在看博客,都在写博客,都听说过博客.在前面的G ...
- 怎样用Google APIs和Google的应用系统进行集成(5)----怎样把Google Tasks的JSON Schema转换成XML的Schema(XSD)?
前面说了一些Google API的介绍,可是在实际的开发其中,我们可能须要把Google RESTful API返回的JSON数据转换成XML数据输入到第三方系统,这在企业应用集成里面很的常见. 那么 ...
- 谷歌正式发布Google APIs Client Library for .NET
好消息,特大好消息! 英文原文:Google API library for .NET paves the way for Google services on Windows phone 本月 17 ...
- Android SDK Manager Google Apis 下载
本意是想利用google的gcm来实装android推送功能的,很遗憾, google貌似已经停止提供啥服务给国内了,或者说国内想继续使用google 服务暂时变得几乎不可能了.找了个代理来进行goo ...
- gRPC版本的 Google APIs
gRPC将是未来google所有客户端的库标准(DevoxxFR), 这句话的出处: https://twitter.com/chanezon/status/585724143003402240 ...
随机推荐
- JS类定义方式
// 方法1 对象直接量 var obj1 = { v1 : "", get_v1 : function() { return this.v1; }, set_v1 : funct ...
- php查找字符串是否存在
strstr //搜索字符串在另一字符串中的首次出现(对大小写敏感) //该函数返回字符串的其余部分(从匹配点).如未找到则返回 false stristr //查找字符串在另一字符串中第一次出现的位 ...
- KMP求字符串最小循环节
证明1: 对于一个字符串S,长度为L,如果由长度为len的字符串s(字符串s的最小循环节是其本身)循环k次构成,那么字符串s就是字符串S的最小循环节 那么字符串有个很重要的性质和KMP挂钩,即 i ...
- Excel阅读器NPOI
什么是NPOI? NPOI 它是 POI 项目的 .NET 版本号. POI是一个开源的Java读写Excel.WORD等微软OLE2组件文档的项目. 使用 NPOI 你就能够在没有安装 Office ...
- Android中一个类实现的接口数不能超过七个
近期一段时间,在开发Android应用程序的过程中,发现Android中一个类实现的接口数超过七个的时候,常常会出现超过第7个之后的接口不能正常使用.
- 使用CSS如何悬停背景颜色变色 onmouseover、onmouseout
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...
- MySQL InnoDB存储引擎undo redo解析
本文介绍MySQL数据库InnoDB存储引擎重做日志漫游 00 – Undo Log Undo Log 为了实现事务原子,在MySQL数据库InnoDB存储引擎,还使用Undo Log(简称:MVCC ...
- 网站通常使用一些javascript包裹 简化电话
//对于Web地址参数 //前面加"=="进行标识,否则直接返回 //解码时依据是否含有"=="标识来决定是否要解码 var base64EncodeChars ...
- NServiceBus开发
使用NServiceBus开发分布式应用 系列主题:基于消息的软件架构模型演变 NServiceBus 是一个.Net平台下开源的消息服务框架,这类产品有时也被称作ESB(Enterprise Ser ...
- hdu 5091 Beam Cannon(扫描线段树)
题目链接:hdu 5091 Beam Cannon 题目大意:给定N个点,如今要有一个W∗H的矩形,问说最多能圈住多少个点. 解题思路:线段的扫描线,如果有点(x,y),那么(x,y)~(x+W,y+ ...