如何使用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 ...
随机推荐
- JUnit4.8.2来源分析-6.1 排序和过滤
Runner.sort.Request.sortWith和Sorter.apply yqj2065很快,他们搞死. Sorter.apply().Request.sortWith()和Sortable ...
- 工厂方法模式(factory method pattern)
工厂方法模式相对于简单工厂模式的长处是为了更好的拓展,当假设再新加一种产品,对于简单工厂模式来说须要改动核心的工厂类,但对于工厂方法模式则不须要,在工厂方法模式中核心的工厂类不再负责创建全部产品的创建 ...
- ReactNavtive框架教程(2)
, alignItems: 'center' } }); 标准的 CSS 属性.尽管用CSS比在IB设置UI样式的可视化要差.但总比在viewDidLoad()方法中用代码写要好一些. 然后增加下面代 ...
- hdu3709(数位dp)
求区间[l,r]内有多少个数的满足: 选一个位为中点,是的左边的数到该位的距离等于右边的位到该位的距离. 比如4139 选择3位中点, 那么左边的距离是 4 * 2 + 1 * 1 , 右边的距 ...
- mysql替换字段里数据内容部分字符串(亦可用于增加字段中的内容)
mysql替换表的字段里面内容,如例子: mysql> select host,user from user where user='testuser'; +----------------- ...
- JDBC连接数据库和释放连接
用久了hibernate现在对于JDBC是怎么实现数据库的连接和释放,所以特地总结下关于JDBC的知识,目的是用于提醒自己很多Java的基础知识需要健全. package com.ssh.action ...
- 设备Oracle当误差:环境不符合要求》》解决方法
一旦安装Oracle当我常常会遇到这样的问题.也没太在意,改了一下client\stage\cvu文件夹cvu_prereq.xml档(添加支持目前的操作系统信息)为了克服,我没有做笔记,但后来有同学 ...
- leetCode Min Stack解决共享
原标题:https://oj.leetcode.com/problems/min-stack/ Design a stack that supports push, pop, top, and ret ...
- Effective C++:规定20: 宁pass-by-reference-to-const更换pass-by-value
(一) 假设传递参数当函数被调用pass-by-value,然后函数的参数是基于实际参数的副本最初值,调用,也得到该函数返回的结束值复印件. 请看下面的代码: class Person { publi ...
- Div 滚动栏滚动到指定的位置
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...