我需要从JSON-Schema + Data中获取所需字段的列表。
目前,我们正在使用AJV在我们的表单中使用JSON Schema获取错误消息,并且它运行良好。
我需要一种方法来获取所有必需的字段(即使已填充),以便将这些字段标记为*为“required”。必填字段可能会根据架构和数据组合而改变。
还尝试通过黑客攻击tv4来提取必填字段但未成功。
请帮忙。
此类架构的示例:
{
"type": "object",
"required": [
"checkbox"
],
"properties": {
"checkbox": {
"type": "boolean"
},
"textbox": {
"type": "string"
}
},
"oneOf": [
{
"required": [
"textbox"
],
"properties": {
"checkbox": {
"enum": [
true
]
}
}
},
{
"properties": {
"checkbox": {
"enum": [
false
]
}
}
}
],
"additionalProperties": false
}
答案 0 :(得分:1)
重读你的问题,最简单的方法就是做你想做的事情
样本1
for(let prop in data) {
if(data.hasOwnProperty(prop) {
//set value to null, -1, or some other universally bad value
data[prop]...value = null;
}
}
样本2
let result = tv4.validateMultiple(data, schema);
let required = result.errors;
答案 1 :(得分:0)
我们通过以下方式解决了这个问题:
分叉tv4(tv4 - 因为它很容易编辑):
https://github.com/mikila85/tv4
输出“Requireds”数组。
我们迭代了每个必填字段,清空了它的数据并将数据+模式发送到AJV进行验证(AJV而不是tv4,因为它解析速度更快)。
通过这样做,我们可以分别知道给定数据所需的字段。
这些是我们提出的工作功能(不是最干净但有助于理解)
function getAllRequiredFields() {
var allRequiredFields = tv4.validateMultiple($scope.formModel, $scope.formSchema).requireds;
allRequiredFields = allRequiredFields.filter(function onlyUnique(value, index, self) {
return self.indexOf(value) === index;
});
return allRequiredFields;
}
function getRequiredFields() {
var t0 = performance.now();
//should be called every model change because of optimization in tv4 for the data+schema.
var allRequiredFields = getAllRequiredFields();
angular.forEach(allRequiredFields, function (requiredPath) {
var modelWithDeletedRequiredProperty = angular.copy($scope.formModel);
deleteValue(modelWithDeletedRequiredProperty, requiredPath);
if (!validateForm(modelWithDeletedRequiredProperty)) {
var requiredError = getErrorObjectsArray(validateForm.errors).find(function (error) {
return error.path === requiredPath;
});
if (requiredError) {
localValidation[requiredError.inputName] = localValidation[requiredError.inputName] || {};
localValidation[requiredError.inputName].isRequired = true;
requiredFieldsPath.push(requiredError.inputName);
}
}
});
var t1 = performance.now();
console.log("form checking took " + (t1 - t0) + " milliseconds.");
}
答案 2 :(得分:-1)
这个函数递归地抓取模式索引,所以也许你可以稍微调整一下
df <- data.frame(Id = 101:107,
Col1 = c("a-b-c-d", "a-c-d", "a-b", "a-b", "b-a", "b-a", "a-c-b"))
forcats::fct_relabel(df$Col1,
function(levs){
sapply(strsplit(levs, '-'),
function(lev) paste(sort(lev), collapse = '-'))
})
#> [1] a-b-c-d a-c-d a-b a-b a-b a-b a-b-c
#> Levels: a-b a-b-c-d a-b-c a-c-d
forcats::lvls_revalue(df$Col1,
sapply(strsplit(levels(df$Col1), '-'),
function(x){paste(sort(x), collapse = '-')}))
#> [1] a-b-c-d a-c-d a-b a-b a-b a-b a-b-c
#> Levels: a-b a-b-c-d a-b-c a-c-d