JSONPath 处理特殊字符

jsonpath,处理,特殊字符 · 浏览次数 : 621

小编点评

**JSONPath基础语法** * `$` 表示文档根元素 * `@` 表示文档当前元素 * `node_name` 或 ['node_name'] 匹配下级节点[index] 检索数组中的元素[start:end:step] 支持数组切片语法* 作为通配符,匹配所有成员.. 子递归通配符,匹配成员的所有子元素(<expr>) 使用表达式?(<boolean expr>)进行数据筛选跟Xpath的对比XPathJsonPath说明/$文档根元素.@当前元素/.或[]匹配下级元素..N/A匹配上级元素,JsonPath不支持此操作符//..递归匹配所有子元素**通配符,匹配下级元素@N/A匹配属性,JsonPath不支持此操作符[][]下标运算符,根据索引获取元素,XPath索引从1开始,JsonPath索引从0开始 **示例代码** ```python import jsonpath # 测试 JSON 数据 s = '{"stor.e":"hello", "stor@e":"hallo"}' # 解析 JSON 数据 result = jsonpath.JSONPath(s, '$.stor\x40e') # 打印结果 print(result) ``` **输出** ```json ['hello'] ``` **注意** * `\x40` 是 JSON 字符串中 @ 的 16进制表示。 * `\x2ee` 是 JSON 字符串中 `@` 的 16进制表示。

正文

JSONPath 处理特殊字符

 先来看看jsonpath的基础

语法

  • $ 表示文档的根元素
  • @ 表示文档的当前元素
  • .node_name['node_name'] 匹配下级节点
  • [index] 检索数组中的元素
  • [start:end:step] 支持数组切片语法
  • * 作为通配符,匹配所有成员
  • .. 子递归通配符,匹配成员的所有子元素
  • (<expr>) 使用表达式
  • ?(<boolean expr>)进行数据筛选

跟Xpath的对比

XPath JsonPath 说明
/ $ 文档根元素
. @ 当前元素
/ .[] 匹配下级元素
.. N/A 匹配上级元素,JsonPath不支持此操作符
// .. 递归匹配所有子元素
* * 通配符,匹配下级元素
@ N/A 匹配属性,JsonPath不支持此操作符
[] [] 下标运算符,根据索引获取元素,XPath索引从1开始,JsonPath索引从0开始
` ` [,]
N/A [start:end:step] 数据切片操作,XPath不支持
[] ?() 过滤表达式
N/A () 脚本表达式,使用底层脚本引擎,XPath不支持
() N/A 分组,JsonPath不支持
  • 注意
    • JsonPath的索引从0开始计数
    • JsonPath中字符串使用单引号表示,例如:$.store.book[?(@.category=='reference')]中的'reference'

DEMO

{
	"store": {
		"book": [{
				"category": "reference",
				"author": "Nigel Rees",
				"title": "Sayings of the Century",
				"price": 8.95
			}, {
				"category": "fiction",
				"author": "Evelyn Waugh",
				"title": "Sword of Honour",
				"price": 12.99
			}, {
				"category": "fiction",
				"author": "Herman Melville",
				"title": "Moby Dick",
				"isbn": "0-553-21311-3",
				"price": 8.99
			}, {
				"category": "fiction",
				"author": "J. R. R. Tolkien",
				"title": "The Lord of the Rings",
				"isbn": "0-395-19395-8",
				"price": 22.99
			}
		],
		"bicycle": {
			"color": "red",
			"price": 19.95
		}
	}
}
XPath JsonPath Result
/store/book/author $.store.book[*].author 所有book的author节点
//author $..author 所有author节点
/store/* $.store.* store下的所有节点,book数组和bicycle节点
/store//price $.store..price store下的所有price节点
//book[3] $..book[2] 匹配第3个book节点
//book[last()] $..book[(@.length-1)],或 $..book[-1:] 匹配倒数第1个book节点
//book[position()<3] $..book[0,1],或 $..book[:2] 匹配前两个book节点
//book[isbn] $..book[?(@.isbn)] 过滤含isbn字段的节点
//book[price<10] $..book[?(@.price<10)] 过滤price<10的节点
//* $..* 递归匹配所有子节点

处理特殊字符的一个应用

  • 来自一个同学的问题

  • 来看具体的代码

    import jsonpath
    s = {
        "stor.e":"hello",
        "stor@e":"hallo"
    }
    print(hex(ord('@')))  # 0x40
    print(hex(ord('.')))  # 0x2e
    print(jsonpath.jsonpath(s, '$.stor\x40e'))  # ['hallo']
    print(jsonpath.jsonpath(s, '$.stor\x2ee'))  # False
    
  • 可以看到上面的代码中,json串有特殊字符,如@如.,但@的ASCII的16进制是40,可以通过这种方式得到hallo,但.却不行了。

  • 上面的代码import jsonpath用的库是jsonpath


  • 那jsonpath其实有很多的实现,我们可以用jsonpath-python

    
    import jsonpath
    s = {
        "stor.e":"hello",
        "stor@e":"hallo"
    }
    print(jsonpath.JSONPath("stor'.'e").parse(s))  # ['hello']
    print(jsonpath.JSONPath("stor'@'e").parse(s))  # ['hallo']
    
    
  • 这样就比较轻松了

  • 可以参考https://github.com/zhangxianbing/jsonpath-python

参考资料

与JSONPath 处理特殊字符相似的内容: