通用数据引用表示法:基于协议-URI-JSONPath的简洁数据定位规范

通用数据引用表示法:基于协议-URI-JSONPath的简洁数据定位规范

1. 概述

基于协议-URI-JSONPath的模式,隐藏JSONPath的根节点$前缀,提供简洁的数据引用表示法。

2. 语法规范

2.1 完整格式

复制代码
<protocol>://<uri>#<jsonpath>

其中:

  • protocol:资源访问协议
  • uri:资源标识符(根据协议而变化)
  • jsonpath:JSONPath表达式,省略根节点$

2.2 协议支持

协议 描述 示例
file 本地文件系统 file:///data/config.json#settings.db
http/https HTTP资源 https://api.example.com/data.json#items[0]
data 内联数据(RFC2397) data:application/json,...#key
redis Redis存储 redis://localhost:6379/0#config.app
env 环境变量 env://DATABASE_URL#host

2.3 JSONPath简化规则

  1. 隐藏根节点 :所有表达式省略开头的$
  2. 自动补全 :解析时自动添加$前缀
  3. 特殊字符
    • 保持., [], *, ?()等标准语法
    • 支持点表示法和括号表示法混合使用

3. EBNF 语法定义

复制代码
(* 完整UDRS语法 *)
udrs-reference = protocol "://" uri [ "#" jsonpath ] ;

(* 协议部分 *)
protocol = scheme ;
scheme = letter, { letter | digit | "+" | "-" | "." } ;

(* URI部分 - 简化定义 *)
uri = uri-scheme-data | uri-path-data ;
uri-scheme-data = scheme-data ; (* 如data:协议 *)
uri-path-data = [ authority ] path ;

authority = "//" [ userinfo "@" ] host [ ":" port ] ;
userinfo = { unreserved | sub-delims | ":" } ;
host = hostname | ipv4address | ipv6address ;
port = digit, { digit } ;
path = { segment } ;

(* JSONPath部分 *)
jsonpath = [ root ] path-expr ;
root = "$" | "@" ;  (* 可选,通常省略 *)
path-expr = segment-expr, { ( "." segment-expr ) | bracket-expr } ;

segment-expr = identifier | wildcard ;
bracket-expr = "[", subscript, "]" ;
subscript = numeric-subscript | string-subscript | wildcard | slice | filter-expr ;

numeric-subscript = integer | negative-integer ;
string-subscript = single-quoted-string | double-quoted-string ;
slice = [ integer ], ":", [ integer ], [ ":", [ integer ] ] ;
filter-expr = "?(", boolean-expr, ")" ;

(* 基本元素 *)
identifier = ( letter | "_" ), { letter | digit | "_" } ;
wildcard = "*" ;
integer = [ "-" ], digit, { digit } ;
negative-integer = "-", digit, { digit } ;

(* 字符串 *)
single-quoted-string = "'", { char - "'" }, "'" ;
double-quoted-string = '"', { char - '"' }, '"' ;

(* 布尔表达式 - 简化 *)
boolean-expr = simple-expr, { ( "&&" | "||" ), simple-expr } ;
simple-expr = "@", path-expr, comparison-op, ( literal | "@", path-expr ) ;
comparison-op = "==" | "!=" | "<" | "<=" | ">" | ">=" ;

(* 字面量 *)
literal = string-literal | number-literal | boolean-literal | null-literal ;
string-literal = '"', { char - '"' }, '"' ;
number-literal = integer, [ ".", digit, { digit } ], [ exponent ] ;
exponent = ( "e" | "E" ), [ "+" | "-" ], digit, { digit } ;
boolean-literal = "true" | "false" ;
null-literal = "null" ;

(* 字符类 *)
letter = "a".."z" | "A".."Z" ;
digit = "0".."9" ;
char = ? any Unicode character ? ;

(* URI保留字符 *)
unreserved = letter | digit | "-" | "." | "_" | "~" ;
sub-delims = "!" | "$" | "&" | "'" | "(" | ")" | "*" | "+" | "," | ";" | "=" ;

4. 解析规则

4.1 解析流程

  1. 协议解析 :提取://前的部分
  2. URI解析 :提取#前的部分(使用标准URI解析)
  3. JSONPath解析
    • 如果#后为空:默认为$(根节点)
    • 如果以$@开头:按标准JSONPath处理
    • 否则:自动添加$前缀

4.2 示例解析

UDRS表示法 解析后JSONPath 描述
file:///data.json#store.book[0] $.store.book[0] 自动添加$
file:///data.json#$.store.book[0] $.store.book[0] 已包含$,保持不变
file:///data.json#@.name @.name 当前节点,不变
file:///data.json# $ 空路径 → 根节点
file:///data.json $ 无路径 → 根节点
https://example.com/a.json#items[*].id $.items[*].id 通配符数组

5. 特殊语法支持

5.1 转义规则

复制代码
# 点号转义
users."john.doe".email  →  users['john.doe'].email

# 引号转义
users.'O\'Brien'.name   →  users["O'Brien"].name

5.2 内联数据

复制代码
data:application/json,{"items":[{"id":1}]}#items[0]

5.3 查询表达式

复制代码
# 过滤器表达式
file://data.json#users[?(@.age >= 18)].name

# 切片操作
file://data.json#items[0:5:2]

# 组合使用
file://data.json#users[?(@.active)].emails[*]

6. 错误处理

6.1 语法错误

  • 无效协议unknown://...
  • URI格式错误file://invalid[path].json#...
  • JSONPath语法错误file://data.json#invalid..path

6.2 语义错误

  • 资源不存在file:///nonexistent.json#...
  • 路径不存在file://data.json#nonexistent.key
  • 类型不匹配file://data.json#items.name(items为数组)

7. 扩展建议

7.1 可选的类型提示

复制代码
file://config.yaml#settings.database<uri>

7.2 默认值语法

复制代码
file://config.json#timeout|30

7.3 函数应用

复制代码
file://data.json#items|length()

7.4 相对引用

复制代码
# 当前文件相对路径
./config.json#key
../parent.json#key

# 使用base URI解析
<base>file:///base/path/</base>
sub/config.json#key  →  file:///base/path/sub/config.json#key

8. 实现建议

8.1 解析库功能

  1. 分离解析:可单独获取协议、URI、JSONPath
  2. 规范化:统一处理相对路径、编码
  3. 验证:语法验证和资源验证分离
  4. 缓存:资源获取缓存机制

8.2 安全性

  1. 沙箱:限制文件系统访问
  2. 递归限制:防止循环引用
  3. 资源限制:限制远程资源大小
  4. 白名单:协议和域名白名单

9. 与现有标准的关系

9.1 兼容性

  • URI标准:完全兼容RFC 3986
  • JSONPath:兼容RFC 9535(JSONPath草案)
  • URI片段 :遵循#作为片段标识符

9.2 优势

  • 简洁性 :隐藏了冗余的$前缀
  • 统一性:统一了本地和远程资源引用
  • 可扩展:支持多种协议和数据格式
  • 可读性:更接近自然语言表达

这个规范平衡了简洁性和表达能力,同时保持了与现有标准的兼容性。

相关推荐
陌上丨1 天前
Redis常用的数据类型有哪些?Zset的底层数据结构是什么?
数据结构·数据库·redis
电商API_180079052471 天前
得物商品详情API接入与优化实战指南
大数据·数据库·人工智能·数据分析·网络爬虫
正在走向自律1 天前
KingbaseES数据库MongoDB兼容模式实战:协议级兼容实现业务平滑迁移
数据库·mongodb·国产数据库·kingbasees·电科金仓
henujolly1 天前
what`s Oracle Problem
数据库·oracle
檀越剑指大厂1 天前
金仓数据库:多模融合,一库承载未来,驱动数字化转型新范式
数据库
啊吧怪不啊吧1 天前
极致性能的服务器Redis之String类型及相关指令介绍
网络·数据库·redis·分布式·mybatis
zihan03211 天前
Redis Windows版本默认配置文件,Redis配置不生效解决方案
数据库·redis·缓存
Hgfdsaqwr1 天前
实战:用Python开发一个简单的区块链
jvm·数据库·python
砚边数影1 天前
InfluxDB迁移替换实战:金仓时序数据库如何提高写入性能
数据库·性能优化·时序数据库·kingbase·kingbasees·金仓数据库
eWidget1 天前
InfluxDB迁移至金仓数据库的同城容灾实践:性能显著提升、运维效率优化,某能源企业实现RPO_5秒的高可靠时序数据管理
运维·数据库·能源·时序数据库·kingbase·kingbasees·金仓数据库