在很多的时候 我们都会 需要 将不同格式的数据  转换为 统一的数据格式

 

比如  将Json 源数据 
{
"b": [
{
"c": "reference",
"a": "atliwen",
"t": "Sayings of the Century",
"p": 8.95
}
]
}
转换为

<book>

<category>reference</category>

<author>atliwen</author>

<title>Sayings of the Century</title>

<price>8.95</price>

<remark>种类:reference | 作者:atliwen | 标题:Sayings of the Century |定 价:8.95</remark>

<type>1</type>

<default>默认数据</default>

</book>

由于客户提供的数据源格式不确定 或 其他服务提供的数据格式是我们需要的, 那么通常的做法是  为每个客户或服务 提供的数据 都写一遍 数据的转换 方法

存在的问题是:

    如果客户或服务很多 , 而且还在不停的增长 。 我们将会不挺的 写 数据转换的方法

需求:

   一个统一的转换数据的方法, 只需要配置一下字段映射关系 就可以  接收不同结构的数据  自动转换为统一的数据结构。 不需要我们写任何代码。

根据 这个需求,我通过  XML 的 Xpath   和   JSON     第三方的 jsonPath  写出了这个统一转换数据结构的方法

package com.thoth.Conversion;

import com.jayway.jsonpath.DocumentContext;
import com.jayway.jsonpath.JsonPath;
import com.jayway.jsonpath.internal.JsonContext;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.springframework.util.StringUtils; import java.util.ArrayList;
import java.util.List; public class OrderToXmlOrder
{ /**
* 将下单数据 转换 成EDI 数据
*
* @param order 订单数据
* @param User 用户配置数据
* @return
* @throws Exception
*/
public static String outEdiOrder(String order, String User, Integer type) throws Exception { Long startLong = System.currentTimeMillis(); Document ediUserDocument = DocumentHelper.parseText(User);// 用户配置数据
Element ediUserRoot = ediUserDocument.getRootElement(); Element Edi = DocumentHelper.createDocument().addElement(ediUserRoot.getName());// 数据
//
Out(order, Edi, ediUserRoot, type);
System.out.println("时间:" + (System.currentTimeMillis() - startLong));
return Edi.asXML();
} /**
* 根据 用户配置节点 自动从数据源 查找数据 生成 EDI 数据节点
*
* @param order 数据源
* @param Edi EDI 数据节点
* @param requestorders 用户配置节点
* @param type 1 是 Xml 2 是 json
*/
public static void Out(String order, Element Edi, Element requestorders, Integer type) throws DocumentException { // Xml 值 <![CDATA[444]]>
List<Element> listElements = requestorders.elements();
Document orderDocument = DocumentHelper.createDocument();
DocumentContext de = new JsonContext();
if (type == 1) {
orderDocument = DocumentHelper.parseText(order);// 订单数据
} else {
de = JsonPath.parse(order);
}
for (Element e : listElements) {
getEdiXml(Edi, type, orderDocument, de, e);
} } /**
* 获取 数据源转换成 Edi 的XML
*
* @param Edi EDI Xml
* @param type type 1 是 Xml 2 是 json
* @param orderDocument Xml 数据 源
* @param de JSON 数据源
* @param e 映射数据
*/
private static void getEdiXml(Element Edi, Integer type, Document orderDocument, DocumentContext de, Element e) {
// 是否有下级节点 if (e.nodeCount() != 1) return; String TestValuse = e.getTextTrim();
if (TestValuse == null || TestValuse == "") return;
//default_ 默认值 如果映射表达式 前缀 为default_ 那么 后面的 直接赋值
if (TestValuse.contains("default_")) {
Edi.addElement(e.getName()).addText(TestValuse.replace("default_", ""));
return;
}
String text = "";
String[] strings = TestValuse.split(":");
if (strings.length > 1) {
text = strings[0] + " : ";
TestValuse = strings[1];
} // 获取 字段值
List<String> nodesString = getStrings(type, orderDocument, de, TestValuse); // 表达式 判断是否 有 //Udf23[text()=N] Udf23 节点的值等于 N
if ("type".equals(e.getName().trim())) {
if (nodesString.size() == 0) {
Edi.addElement(e.getName()).addText("0");
return;
}
Edi.addElement(e.getName()).addText("1");
return;
}
orElement(Edi, e, text, nodesString);
} /**
* EDI Xml 字段值 生成
*
* @param Edi Edi Xml
* @param e
* @param text
* @param nodesString
*/
private static void orElement(Element Edi, Element e, String text, List<String> nodesString) {
if (nodesString.size() > 1) {
for (String et : nodesString)
text = text + "," + et;
text = text.substring(1, text.length());
} else text = text + nodesString.get(0); Element element = Edi.element(e.getName()); if (element != null) {
if (StringUtils.isEmpty(element.getText())) {
element.addText(text.trim());
} else {
element.addText(" | " + text.trim());
}
} else {
Edi.addElement(e.getName()).addText(text.trim());
}
} /**
* 赋值
*
* @param type
* @param orderDocument
* @param de
* @param testValuse
* @return
*/
private static List<String> getStrings(Integer type, Document orderDocument, DocumentContext de, String testValuse) {
List<String> nodesString = new ArrayList<>();
if (type == 1) {
List<Element> nodesList = orderDocument.selectNodes(testValuse);
if (nodesList.size() > 0) {
for (Element ea : nodesList)
nodesString.add(ea.getTextTrim());
}
} else {
try {
List<Object> list= de.read(testValuse);
for (Object o:list)
nodesString.add(o.toString());
} catch (Exception ea) {
Object o=de.read(testValuse);
nodesString.add(o.toString());
}
}
return nodesString;
} }

测试 JSON

    /**
* 通过 映射 将 json 结构转换为统一的 Xml 结构
* @throws Exception
*/
@Test
public void jsonToXml() throws Exception { //{
// b: [
// {
// c: "reference",
// a: "atliwen",
// t: "SayingsoftheCentury",
// p: 8.95
// }
// ]
//}
String json ="{\"b\":[{\"c\":\"reference\",\"a\":\"atliwen\",\"t\":\"SayingsoftheCentury\",\"p\":8.95}]}"; //<book>
// <category>$.b..c</category>
// <author>$.b..a</author>
// <title>$.b..t</title>
// <price>$.b..p</price>
// <remark>种类:$.b..c</remark>
// <remark>作者:$.b..a</remark>
// <remark>标题:$.b..t</remark>
// <remark>定价:$.b..p</remark>
// <type><![CDATA[$.b.[?(@.p>100)]]]></type>
// <default>default_默认数据</default>
//</book>
String userMapper="<book><category>$.b..c</category><author>$.b..a</author><title>$.b..t</title><price>$.b..p</price><remark>种类:$.b..c</remark><remark>作者:$.b..a</remark><remark>标题:$.b..t</remark><remark>定价:$.b..p</remark><type><![CDATA[$.b.[?(@.p>100)]]]></type><default>default_默认数据</default> </book>"; String out= OrderToXmlOrder.outEdiOrder(json,userMapper,2);
System.out.println(out);
//<book>
// <category>reference</category>
// <author>atliwen</author>
// <title>SayingsoftheCentury</title>
// <price>8.95</price>
// <remark>种类 : reference | 作者 : atliwen | 标题 : SayingsoftheCentury | 定价 : 8.95</remark>
// <type>0</type>
// <default>默认数据</default>
//</book>
}

测试XML

   @Test
public void XmlToOrderXml() throws Exception { //<b>
// <c>reference</c>
// <a>atliwen</a>
// <t>SayingsoftheCentury</t>
// <p>8.95</p>
//</b>
String xml= "<b><c>reference</c><a>atliwen</a><t>SayingsoftheCentury</t><p>8.95</p></b>"; //<book>
// <category>//c</category>
// <author>//a</author>
// <title>//t</title>
// <price>//p</price>
// <remark>种类://c</remark>
// <remark>作者://a</remark>
// <remark>标题://t</remark>
// <remark>定价://p</remark>
// <type><![CDATA[//p[text()>100]]]></type>
// <default>default_默认数据</default>
//</book>
String userMapper="<book><category>//c</category><author>//a</author><title>//t</title><price>//p</price><remark>种类://c</remark><remark>作者://a</remark><remark>标题://t</remark><remark>定价://p</remark><type><![CDATA[//p[text()>100]]]></type><default>default_默认数据</default></book>"; String out= OrderToXmlOrder.outEdiOrder(xml,userMapper,1);
System.out.println(out); //<book>
// <category>reference</category>
// <author>atliwen</author>
// <title>SayingsoftheCentury</title>
// <price>8.95</price>
// <remark>种类 : reference | 作者 : atliwen | 标题 : SayingsoftheCentury | 定价 : 8.95</remark>
// <type>0</type>
// <default>默认数据</default>
//</book>
}

当前代码还未在正式环境使用,  可能会有 异常。 请注意!

  

通过映射关系 动态转义为统一格式的数据 (支持 JSON 和 XML )的更多相关文章

  1. springmvc 自定义view支持json和jsonp格式数据返回

    1.如果controlloer上用@ResponseBody注解,则用<mvc:message-converter>里面配置的json解析器进行解析 <mvc:annotation- ...

  2. php返回json,xml,JSONP等格式的数据

    php返回json,xml,JSONP等格式的数据 返回json数据: header('Content-Type:application/json; charset=utf-8'); $arr = a ...

  3. json格式的数据及遍历:

    代码: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8 ...

  4. ASP.NET Core的路由[1]:注册URL模式与HttpHandler的映射关系

    ASP.NET Core的路由是通过一个类型为RouterMiddleware的中间件来实现的.如果我们将最终处理HTTP请求的组件称为HttpHandler,那么RouterMiddleware中间 ...

  5. 注册URL模式与HttpHandler的映射关系

    注册URL模式与HttpHandler的映射关系 ASP.NET Core的路由是通过一个类型为RouterMiddleware的中间件来实现的.如果我们将最终处理HTTP请求的组件称为HttpHan ...

  6. System.Data.DbType 与其它DbType的映射关系

    System.Data.DbType 与其它DbType的映射关系 有如下类型的映射对照: System.Data.SqlClient.SqlDbType System.Data.OleDb.OleD ...

  7. Json.Net系列教程 2.Net类型与JSON的映射关系

    原文 Json.Net系列教程 2.Net类型与JSON的映射关系 首先谢谢大家的支持和关注.本章主要介绍.Net类型与JSON是如何映射的.我们知道JSON中类型基本上有三种:值类型,数组和对象.而 ...

  8. Mybatis中输入输出映射和动态Sql

    一.输入映射 我们通过配置parameterType的值来指定输入参数的类型,这些类型可以是简单数据类型.POJO.HashMap等数据类型 1.简单类型 2.POJO包装类型 ①这是单表查询的时候传 ...

  9. 第二节:创建模型,使用Code First,配置映射关系

    这一节,实现模型的创建,配置映射关系 使用Code First数据迁移. 创建模型 一,首先创建几个接口:实体接口,聚合根接口,值对象接口 1,实体接口: 2,聚合根接口: 3,值对象接口: 二,模型 ...

随机推荐

  1. Git提交过程的一些问题

    参考:http://www.cnblogs.com/sinojelly/archive/2011/08/07/2130172.html 提交冲突,无法提交到github git pull origin ...

  2. MySQL5.6-Tomcat7环境变量的配置

    一.MySQL环境变量配置(zip安装):系统-高级系统设置--环境变量--path添加D:\Mysql\bin 找到mysql解压目录下的my-default.ini文件修改 basedir = D ...

  3. UVa 10827 - Maximum sum on a torus

    题目大意:UVa 108 - Maximum Sum的加强版,求最大子矩阵和,不过矩阵是可以循环的,矩阵到结尾时可以循环到开头.开始听纠结的,想着难道要分情况讨论吗?!就去网上搜,看到可以通过补全进行 ...

  4. java中String相等问题

    java中判断两个字符串是否相等的问题   判断两个字符串是否相等的问题.在编程中,通常比较两个字符串是否相同的表达式是"==",但在java中不能这么写.在java中,用的是eq ...

  5. 创建 github 仓库

    1. 创建入口 在右上角找到 “+” 然后,选择 “New repository” 进行创建. 2. 填入信息 输入名字和描述 . 选择 “Initialize this repository wit ...

  6. 关于网页显示乱码问题的一些个人见解(PHP、JSP...)

    最近做项目,遇到了一些网页显示乱码的情况,在网上查了很多资料都没有给一个全面的准确的答案,自己摸索了一下经过对比开发环境(我使用的是Myeclipse)编辑器的编码和浏览器默认显示的编码发现,在字符编 ...

  7. HDU2066:一个人的旅行(Dijkstra)

    Problem Description 虽然草儿是个路痴(就是在杭电待了一年多,居然还会在校园里迷路的人,汗~),但是草儿仍然很喜欢旅行,因为在旅途中 会遇见很多人(白马王子,^0^),很多事,还能丰 ...

  8. js实时显示系统时间

    刚刚在做后台页面最上面要动态显示时间刚写了这个代码 将这段代码加入<head></head> <!--时间显示代码 --><script>functio ...

  9. XML之XPath操作

    在学习XPath之前你应该对XML的节点,元素,属性,原子值(文本),处理指令,注释,根节点(文档节点),命名空间以及对节点间的关系如:父(Parent),子(Children),兄弟(Sibling ...

  10. 使用 Passenger +Apache扩展 Puppet,代替其Webrick的web框架

    使用 Passenger +Apache扩展 Puppet,代替其Webrick的web框架 1安装 yum install ruby-devel ruby-libs rubygems libcurl ...