XML和Json不仅是结构化文本,而且擅长表示多层数据,可承载足够通用和足够丰富的信息,因此常被用于各种数据交换和信息传递事务,比如WebService/Restful,微服务等。但多层数据要比传统的二维表结构复杂,取数后再处理的难度也大。
早期,没有专业的json/XML的后处理技术,JAVA开发者通常要采取硬写代码或入库再算的方式。硬编码计算能力差,代码量大,开发效率很低。入库虽然解决了部分计算能力,但步骤多,延迟大,额外制造了JAVA与数据库的紧耦合,架构性很差,而且数据库只擅长计算二维表,处理多层结构化数据的能力并不强。后来,专业的json/XML后处理技术开始出现,才使Java中做这些运算处理的效率有了较大的提升,JsonPath/XPath是其中的优秀者。
JsonPath和XPath具有突破性的计算能力
XPath是广泛使用的XML处理语言,内置于XOM/Xerces-J/Jdom/Dom4J等函数库。JsonPath仿照XPath的语法,实现了类似的功能,且有自己的函数库,目前是广泛使用的Json处理语言。比起以前硬编码的方式,XPath/JsonPath代码简短得多,具有突破性的计算能力。
比如,用arronlong HTTP函数库从WebService取XML字符串,使用Dom4J函数库将XML字符串解析为Document类型,使用Dom4J内置的XPath语法进行条件查询:
String path= "http://.../emp_orders.xml";
String XMLStr= com.arronlong.httpclientutil.HttpClientUtil.get(com.arronlong.httpclientutil.common.HttpConfig.custom().url(path));
Document doc = DocumentHelper.parseText(XMLStr);
List<Node> list=doc.selectNodes("/xml/row/Orders[Amount>1000 and Amount<=3000 and contains(Client,'bro')]")
类似地,用JsonPath进行条件查询:
String path= "http://.../emp_orders.json";
String JsonStr= com.arronlong.httpclientutil.HttpClientUtil.get(com.arronlong.httpclientutil.common.HttpConfig.custom().url(path));
Object document = Configuration.defaultConfiguration().jsonProvider().parse(JsonStr);
ArrayList l=JsonPath.read(document, "$[*].Orders[?(@.Amount>1000 && @.Amount<2000 && @.Client =~ /.*?business.*?/i )]");
JsonPath与XPath用法类似,语法相通,计算能力差别不大,下面以JsonPath为主进行说明。JsonPath/XPath对条件查询的支持比较完整,包括关系运算符,如大于、小于等于;逻辑运算符,如与、或、非;字符串正则表达式,如~ /.?business.?/i;字符串函数,如模糊匹配contains。此外,JsonPath/XPath还支持在条件查询中使用数学运算符(函数),如±*、div;位置函数,如position、last;日期函数,如year-from-date、timezone-from-time。
需要特别说明的是,JsonPath/XPath可以灵活表达条件查询的层级范围,包括绝对位置、相对位置、父节点、子节点、属性、元素等,这是多层数据处理语言有别于二维数据处理语