在JSON字符串中定位到对象路径

格言

我有一个与此相似的JSON字符串:

{
    "Version": "XXX",
    "Statements": [
        {...},
        {...},
        {...}
    ]
}

我如何找出Statements属性内的哪个对象是在XXJSON字符串的字符定义的(考虑到那些对象可以具有任意深度的嵌套)。

例如,如果我有一个字符串

{"Version":"XXX","Statements":[{"a":1},{"b":2},{"b":3}]}
--------------------------------------------------------
123456789 123456789 123456789 123456789 123456789 123456

那么位置处的字符36将与第一个语句对象相对应,而位置处的字符52将与第三个语句对象相对应。

格言

经过大量研究,我认为我有一个前进的方向,那就是不使用esprima编写自己的解析器由于esprima并非特定于JSON(而是JavaScript),因此我必须将JSON字符串包装在方括号中。

树中的每个元素都包含loc属性,该属性的范围与它在原始JSON字符串中的位置匹配。

var esprima = require("esprima");
var JSONPath = require('JSONPath');

function getStatementIndex(str, line, column) {
	var tree = esprima.parseScript(str, {loc:true});
	var query = "$.body[0].expression.properties[?(@.key.value=='Statement')].value.elements[*].loc";
	var locations = JSONPath({json: tree, path: query});
	
	console.log(locations);
	
	for(var i = 0; i < locations.length; i++) {
		var loc = locations[i];
		
		var contains = false;
		
		if (loc.start.line < line && loc.end.line > line) {
			continue;
		}
		
		// If a single line and in between
		if (loc.start.line == loc.end.line && loc.start.line == line) {
			if (loc.start.column <= column && loc.end.column >= column) {
				contains = true;
			}
			
		// If on the beginning line
		} else if (loc.start.line == line && loc.start.column <= column) {
			contains = true;
		
		// If on the end line
		} else if (loc.end.line == line && loc.end.column >= column) {
			contains = true;
		
		// If in between
		} else if (loc.start.line < line  && loc.end.line > line) {
			contains = true;
		}
					
		if (contains)
			return i;
	}
	
	return -1;
}

var result = getStatementIndex(str, 81, 7);

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章