如何在Monaco Editor中通过路径查找JSON的行号?
在Monaco Editor中通过路径定位JSON节点的行号
需求说明
实现一个getLineByPath函数,传入JSON节点的路径数组(如['pages', 0, 'text']),返回该节点在Monaco Editor中对应的行号。
示例
给定以下JSON内容:
{ "pages": [ { "text": "test" } ] }
调用getLineByPath(['pages', 0, 'text']),预期返回4(Monaco编辑器行号从1开始计数)。
实现方案
利用Monaco Editor自带的JSON语言服务解析文本为AST,遍历路径定位节点后获取行号:
function getLineByPath(path) { // 获取当前编辑器模型 const model = editor.getModel(); if (!model) return -1; // 初始化JSON语言服务 const jsonService = monaco.languages.json.jsonDefaults.getLanguageService(); const text = model.getValue(); const uri = model.uri; // 解析JSON生成带位置信息的文档对象 const jsonDoc = jsonService.parseJSONDocument(uri, text); let currentNode = jsonDoc.root; // 按路径遍历节点 for (const segment of path) { if (!currentNode) break; if (Array.isArray(currentNode.children)) { if (typeof segment === 'number') { // 匹配数组索引对应的元素节点 currentNode = currentNode.children.find(child => child.type === 'arrayElement' && child.index === segment ); currentNode = currentNode?.children?.[0]; } else { // 匹配对象属性对应的取值节点 currentNode = currentNode.children.find(child => child.type === 'property' && child.keyNode?.value === segment ); currentNode = currentNode?.valueNode; } } else { currentNode = null; } } // 返回1-based行号,未找到则返回-1 return currentNode?.range?.startLineNumber || -1; }
注意事项
- 确保JSON内容符合标准格式(如键名带双引号),否则解析会失败
- 路径中的数组索引需为数字类型,对象属性需为字符串类型
- 若路径无效或节点不存在,函数返回
-1
内容的提问来源于stack exchange,提问作者Eric Flat
相关产品推荐
相关产品推荐

