You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Monaco编辑器中获取hover位置对应的JSON Schema路径?

Monaco编辑器自定义JSON Hover:获取对应Schema路径的方案

一、直接利用Monaco内置JSON语言服务实现

Monaco的JSON语言服务本身已存储JSON节点与Schema的关联信息,无需额外依赖即可完成需求:

  1. 定位Hover对应的JSON AST节点
    通过编辑器模型和Hover位置,解析出目标JSON节点:

    const editor = monaco.editor.getEditorById('your-editor-id');
    const model = editor.getModel();
    const hoverPosition = editor.getPosition(); // 或从hover事件参数中获取position
    const offset = model.getOffsetAt(hoverPosition);
    
    // 获取JSON语言服务实例
    const jsonService = monaco.languages.json.JSONLanguageService.getService();
    // 解析JSON内容生成AST文档
    const jsonDoc = jsonService.parseJSON(model.getValue());
    // 根据偏移量找到对应的AST节点
    const targetNode = jsonDoc.getNodeFromOffset(offset);
    
  2. 匹配对应的Schema片段
    利用AST节点的path属性(数组格式,如["user", "age"]),结合自定义Schema遍历定位:

    const yourSchema = /* 你的自定义JSON Schema对象 */;
    let currentSchemaPart = yourSchema;
    
    // 按节点路径遍历Schema
    for (const segment of targetNode.path) {
      if (currentSchemaPart.properties?.[segment]) {
        currentSchemaPart = currentSchemaPart.properties[segment];
      } else if (currentSchemaPart.items && typeof segment === 'number') {
        currentSchemaPart = currentSchemaPart.items;
      }
      // 可根据Schema结构扩展oneOf、anyOf等特殊场景的处理逻辑
    }
    
    // currentSchemaPart即为Hover位置对应的Schema片段
    

    也可以直接调用语言服务的getHoverContent方法,从返回结果中提取Schema相关信息,省去手动遍历的步骤:

    const hoverContent = await jsonService.getHoverContent(model, hoverPosition);
    // hoverContent.contents包含Schema描述等信息,可解析提取对应路径或片段
    

二、第三方库通用方案(脱离Monaco依赖)

如果需要更灵活的实现,或不想依赖Monaco内部API,可采用以下工具组合:

  • json-source-map:处理JSON字符串的位置映射,解决空白字符导致的位置偏移问题,精准定位Hover位置对应的JSON节点路径
  • json-schema-traverse:遍历JSON Schema,根据节点路径快速匹配对应的Schema片段

实现步骤:

  1. 安装依赖

    npm install json-source-map json-schema-traverse
    
  2. 定位JSON节点路径
    用json-source-map解析JSON内容,匹配Hover位置对应的节点路径:

    import { parse } from 'json-source-map';
    
    const jsonContent = model.getValue(); // 从Monaco模型获取JSON内容
    const hoverPosition = editor.getPosition();
    
    // 解析JSON生成位置映射表
    const { pointers } = parse(jsonContent);
    let targetPath = null;
    
    // 遍历所有节点指针,找到匹配Hover位置的节点
    for (const [pathStr, info] of Object.entries(pointers)) {
      const { key, value } = info;
      // 检查Hover位置是否在节点的key或value范围内
      const inKeyArea = key && hoverPosition.lineNumber === key.line + 1 && hoverPosition.column >= key.column && hoverPosition.column <= key.column + key.length;
      const inValueArea = value && hoverPosition.lineNumber === value.line + 1 && hoverPosition.column >= value.column && hoverPosition.column <= value.column + value.length;
      
      if (inKeyArea || inValueArea) {
        // 将路径字符串转为数组格式(如"/user/age"转为["user", "age"])
        targetPath = pathStr.split('/').filter(Boolean);
        break;
      }
    }
    
  3. 遍历Schema匹配对应片段
    用json-schema-traverse根据节点路径定位Schema:

    import traverse from 'json-schema-traverse';
    
    const yourSchema = /* 你的自定义JSON Schema对象 */;
    let targetSchemaPart = yourSchema;
    
    traverse(yourSchema, {
      cb: (schema, jsonPath) => {
        // 匹配当前Schema路径与目标节点路径
        if (JSON.stringify(jsonPath) === JSON.stringify(targetPath)) {
          targetSchemaPart = schema;
        }
      }
    });
    
    // targetSchemaPart即为Hover位置对应的Schema片段
    

内容的提问来源于stack exchange,提问作者mwag

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.06 10:35:24