笔者电话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. JUnit4.8.2来源分析-6.1 排序和过滤

    Runner.sort.Request.sortWith和Sorter.apply yqj2065很快,他们搞死. Sorter.apply().Request.sortWith()和Sortable ...

  2. 工厂方法模式(factory method pattern)

    工厂方法模式相对于简单工厂模式的长处是为了更好的拓展,当假设再新加一种产品,对于简单工厂模式来说须要改动核心的工厂类,但对于工厂方法模式则不须要,在工厂方法模式中核心的工厂类不再负责创建全部产品的创建 ...

  3. ReactNavtive框架教程(2)

    , alignItems: 'center' } }); 标准的 CSS 属性.尽管用CSS比在IB设置UI样式的可视化要差.但总比在viewDidLoad()方法中用代码写要好一些. 然后增加下面代 ...

  4. hdu3709(数位dp)

    求区间[l,r]内有多少个数的满足:   选一个位为中点,是的左边的数到该位的距离等于右边的位到该位的距离. 比如4139  选择3位中点, 那么左边的距离是 4 * 2 + 1 * 1 , 右边的距 ...

  5. mysql替换字段里数据内容部分字符串(亦可用于增加字段中的内容)

    mysql替换表的字段里面内容,如例子: mysql> select host,user from user  where user='testuser'; +----------------- ...

  6. JDBC连接数据库和释放连接

    用久了hibernate现在对于JDBC是怎么实现数据库的连接和释放,所以特地总结下关于JDBC的知识,目的是用于提醒自己很多Java的基础知识需要健全. package com.ssh.action ...

  7. 设备Oracle当误差:环境不符合要求》》解决方法

    一旦安装Oracle当我常常会遇到这样的问题.也没太在意,改了一下client\stage\cvu文件夹cvu_prereq.xml档(添加支持目前的操作系统信息)为了克服,我没有做笔记,但后来有同学 ...

  8. leetCode Min Stack解决共享

    原标题:https://oj.leetcode.com/problems/min-stack/ Design a stack that supports push, pop, top, and ret ...

  9. Effective C++:规定20: 宁pass-by-reference-to-const更换pass-by-value

    (一) 假设传递参数当函数被调用pass-by-value,然后函数的参数是基于实际参数的副本最初值,调用,也得到该函数返回的结束值复印件. 请看下面的代码: class Person { publi ...

  10. Div 滚动栏滚动到指定的位置

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...