如何将 json 文件夹加载到 Javascript?

How to load a json folder into Javascript?

我想加载(要求)一个包含 json 架构的文件夹,这些架构具有基于其文件的引用。

也就是说我有

Schema1: 
{ //Schema stuff ....
    "$ref": "./json_schema2_file.json#someElement"
}

并且在同一文件夹中的另一个文件中:

Schema2
{//Schema stuff...
"$id": "/someElement"
}

这些模式在单独的文件中,现在应该加载到 JS 中以针对 json 对象进行验证。 但是,文件夹内的引用应该仍然有效。

这就是为什么我的问题是,是否以及如何加载充满 json 文件的文件夹而不中断引用。

这些模式将被此库用于验证 json 个对象:https://github.com/tdegrunt/jsonschema 我个人将 Node 与 Angular 一起使用,因此使用 fs 仅适用于 node,但这将是一个开始。

在您的 Node 后端,require 可用于导入 JSON 文件,就好像它是普通的 JavaScript 文件一样:

// data.json
{ "hello": "world" }

// main.js
const data = require('./data.json');
console.log(data); // { hello: 'world' }

对于您的 Angular 前端,这取决于您构建捆绑包的方式,但通常使用 import data from './data.json' 应该会产生相同的结果(如 中所述)。


现在问题来了:如果您的模式在多个 JSON 文件中,您能做什么?

requireimport 本身都不会花时间解析 $ref$id 属性并将所有内容捆绑到单个 JS 对象中。似乎没有任何简单的本机方法来解析所有内容,幸运的是 NPM 包 json-schema-ref-parser 正是这样做的!它可以在您的用例中使用:

// foo.schema.json 
{
    "type": "object",
    "properties": {
        "bar": {
            "$ref": "./bar.schema.json"
        }
    }
}

// bar.schema.json 
{
    "type": "number"
}

// main.js 
const parser = require('json-schema-ref-parser');
parser.dereference('foo.schema.json', (err, schema) => console.log(schema));
// logs: { type: 'object', properties: { bar: { type: 'number' } } }

1.Write json 内容使用 json 解析器以避免拼写错误。

 {
     "quiz": 
     [
         {
             "question": "Question 1",
             "a": "Answer a",
             "b": "Answer b",
             "c": "Answer c",
             "correct": "a"
         },
         {
             "question": "Question 2",
             "a": "Answer a",
             "b": "Answer b",
             "c": "Answer c",
             "correct": "b"
         },
         {
             "question": "Question 3",
             "a": "Answer a",
             "b": "Answer b",
             "c": "Answer c",
             "correct": "c"
         }
     ]
 }

2.Save json 在与您的 js 脚本相同的文件夹中。我将文件命名为 questions.json。 3.Load json 数据用$.getJSON。以下示例是将问题从 json 加载到 allQuestions 数组的完整脚本。

var allQuestions = new Array();
    
function loadQuestions() {
    $.getJSON('question.json', function (data) {
        allQuestions = data.quiz;
    }).error(function(){
            console.log('error: json not loaded');
        });
    });
}

4.Now 您的 json 数据在 allQuestions 数组中可用,您可以访问它,例如:

var currentQuestion = allQuestions[0].question;
var answerA         = allQuestions[0].a; 

使用 .done 回调 请记住 $getJSON 异步运行。这样的实施将不是最好的主意:

loadQuestions();
printQuestion(allQuestions[0]); 

有可能在调用 printQuestion 的那一刻 JSON 还没有被加载并且 allQuestions 大小将为 0。确保在 JSON 完全加载后完成一些操作, 使用 .done 回调。

var allQuestions = new Array();
    
function loadQuestions() {
    $.getJSON('question.json', function (data) {
        allQuestions = data.quiz;
    })
    .error(function() {
        console.log('error: JSON not loaded'); 
    })
    .done(function() {
        console.log( "JSON loaded!" );
        printQuestion(allQuestions[0]); 
    });
}

通常,JSON 模式解析器(包括我维护的 jsonschema 包)不会自动加载引用。您只需要提供具有架构的附加文件:

var Validator = require('jsonschema').Validator;
var v = new Validator();
v.addSchema(require('./json_schema.json'), 'http://example.com/json_schema.json');
v.addSchema(require('./json_schema2.json'), 'http://example.com/json_schema2.json');

不要忘记为您的模式提供完整的 URI,否则它们可能无法在应用程序之间一致地工作。

如果您想自动导入引用,jsonschema 包提供了一个列表,其中包含 Validator#unresolvedRefs 属性 中没有定义的已知模式。关闭此堆栈并使用 Validator#addSchema:

导入引用
async function importUnresolved(){
    for(var uri; uri = v.unresolvedRefs.shift();){
        // where `get` is some resolver that downloads the schema
        schema = await get(uri);
        if(!schema) throw new Error(`Could not dereference JSON schema: <${uri}>`);
        v.addSchema(schema, uri);
    }
}