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

如何在Fortran/C混合程序中使用JSON Schema验证YAML?

在Fortran/C混合程序中用JSON Schema验证YAML文件

完全可以在你的Fortran/C混合程序中实现YAML的Schema验证,核心思路是先将YAML转换为JSON结构,再借助成熟的C语言JSON Schema验证库完成校验——因为直接的YAML Schema验证库在C生态中可选较少,而JSON Schema的C库已经非常成熟,且YAML是JSON的超集,大部分结构可以无缝映射。

C端实现步骤

  1. 依赖选型

    • 保留现有libyaml用于YAML解析
    • 选择C语言JSON库(如cJSON或jansson)用于构建JSON内存结构
    • 选择JSON Schema验证库(如libjsonschema或jsonschema-validator)完成Schema校验
  2. 具体流程

    • 用libyaml解析YAML文件,生成抽象语法树(AST)
    • 编写转换逻辑,将YAML AST映射为JSON库对应的内存结构(处理标量、序列、映射等YAML类型到JSON的转换)
    • 加载预定义的JSON Schema文件(可编译进程序或运行时读取)
    • 调用JSON Schema库验证转换后的JSON结构
    • 根据验证结果决定是否继续程序流程:验证失败则输出错误并终止,避免程序挂起

Fortran端调用方式

Fortran本身没有原生的JSON Schema验证库,可通过bind(c)调用C端封装好的验证函数:

  1. 在C中封装一个简洁的验证入口函数,接收YAML文件路径和Schema文件路径,返回验证结果码
  2. 在Fortran中通过iso_c_binding声明该C函数,在程序启动或读取YAML前调用,根据返回值判断是否继续执行

代码示例

C端验证函数(伪代码)

#include <yaml.h>
#include <cjson/cJSON.h>
#include <jsonschema.h>

// 辅助函数:将YAML节点转换为cJSON对象
cJSON* yaml_node_to_cjson(yaml_node_t* node) {
    // 实现类型转换逻辑:
    // - 标量节点转JSON字符串/数字/布尔值
    // - 序列节点转JSON数组
    // - 映射节点转JSON对象
}

int validate_yaml(const char* yaml_file, const char* schema_file) {
    // 1. 解析YAML文件
    yaml_parser_t parser;
    yaml_parser_initialize(&parser);
    FILE* f = fopen(yaml_file, "r");
    if (!f) return -1;
    yaml_parser_set_input_file(&parser, f);
    
    yaml_document_t doc;
    if (!yaml_parser_load(&parser, &doc)) {
        fclose(f);
        yaml_parser_delete(&parser);
        return -2; // YAML语法错误
    }
    fclose(f);

    // 2. 转换YAML到JSON
    cJSON* json = yaml_node_to_cjson(yaml_document_get_root_node(&doc));
    yaml_document_delete(&doc);
    yaml_parser_delete(&parser);
    if (!json) return -3; // 转换失败

    // 3. 加载Schema
    cJSON* schema = cJSON_ParseFile(schema_file);
    if (!schema) {
        cJSON_Delete(json);
        return -4; // Schema加载失败
    }

    // 4. 执行Schema验证
    jsonschema_error_t error;
    int result = jsonschema_validate(schema, json, &error);
    
    // 清理资源
    cJSON_Delete(json);
    cJSON_Delete(schema);

    if (result != 0) {
        fprintf(stderr, "YAML validation failed: %s\n", error.message);
        jsonschema_error_free(&error);
        return -5; // 不符合Schema
    }
    return 0; // 验证通过
}

Fortran端调用代码

interface
    function validate_yaml(yaml_path, schema_path) bind(c, name='validate_yaml')
        use, intrinsic :: iso_c_binding
        integer(c_int) :: validate_yaml
        character(kind=c_char), intent(in) :: yaml_path(*)
        character(kind=c_char), intent(in) :: schema_path(*)
    end function validate_yaml
end interface

program yaml_validation_demo
    use, intrinsic :: iso_c_binding
    implicit none
    character(len=256, kind=c_char) :: yaml_file, schema_file
    integer(c_int) :: status

    ! 初始化文件路径(需追加C风格空终止符)
    yaml_file = "config.yaml"//c_null_char
    schema_file = "config_schema.json"//c_null_char

    ! 调用C端验证函数
    status = validate_yaml(yaml_file, schema_file)
    if (status /= 0) then
        print *, "YAML validation failed. Exit code: ", status
        stop 1
    end if

    ! 验证通过,继续执行后续逻辑
    print *, "YAML validation passed. Proceeding..."
end program yaml_validation_demo

关键注意事项

  • YAML到JSON的转换兼容性:需处理YAML特有的特性(如锚点、别名、多行字符串、自定义标签),确保转换后的JSON能准确反映原YAML的语义,避免出现假阳性的验证错误
  • Schema的部署:可将Schema文件编译进程序(如通过二进制资源或硬编码为字符串),减少运行时依赖
  • 错误反馈:验证失败时要输出具体错误位置和原因,方便用户修正YAML文件
  • 性能平衡:对于大体积YAML文件,转换和验证会带来额外开销,可根据场景选择在程序启动时一次性验证,或分阶段验证关键节点

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.20 11:13:20