首页 > 解决方案 > 定义自己的 YAML 语法的简洁方式?

问题描述

对于 XML,有定义所有元素的文档类型定义 (DTD),但是对于 YAML 有类似的东西吗?

我发现了一篇关于 使用 XML DTD 验证 YAML的帖子,它建议无论如何都使用 DTD 和/或简单的 XML,但我怀疑这在我的情况下是否可行:我的项目决定采用(自定义)YAML 格式。从这种格式的 YAML 文件通过算法生成一个相当复杂的 XML。YAML 包含的信息比 XML 少得多,但人类编辑器必须知道的所有重要信息。

目前,我的 YAML 的定义主要是平淡无奇的(作为非常抽象的需求文本),作为解析和转换为 XML 的实际源代码。两者都不适合应该维护 YAML 文件的最终用户。是否有一种简洁明了的方式来定义我的自定义 YAML 语法?

标签: xmlyamldtd

解决方案


首先,YAML 是语法。您要描述的不是语法,而是结构。

YAML 是一种序列化格式。因此,您序列化和反序列化的数据类型是 YAML 文件的结构描述。除非您使用 YAML 进行数据交换,否则您通常会有一个应用程序来实现加载 YAML 文件。

默认情况下,许多 YAML 实现反序列化为列表、字典和简单值(字符串、int 等)的异构结构。但是,如果您假设某个结构,您可以写下定义该结构的类型,然后将您的 YAML 加载到该类型的对象中。简单示例(本例中为 Java):

public class Book {
    public static class Person {
        public String name;
        public int age;
    }

    public Person author;
    public String title;
}

此类型描述了此 YAML 文档的结构:

author:
  name: John Doe
  age: 23
title: Very interesting title

任何能够反序列化为类型的 YAML 实现都能够检查这些类型;在运行时通过反射或在编译时通过宏或其他编译时评估方式。因此,您也可以检查该结构并使用它为用户自动生成文档(可能使用 JavaDoc 注释来扩展文档)。

现在您可以使用动态类型语言。如果该语言是 Python,您仍然可以定义类来定义您的结构,并且可以使用类型提示来定义标量值的类型。这为您提供了用户文档,但是您仍然需要手动实现验证,因为没有强制执行类型提示(PyYAMLadd_path_resolver是此处的重要钩子,可以将文档图的部分解析为特定类型,而无需使用 YAML 标记)。

对于其他语言,可能存在不同的解决方案。通常,最好维护一个描述 YAML 结构的单一事实来源 (SSOT),然后将其用作用户文档和验证的基础。由于 YAML 是一种序列化格式,如果语言和 YAML 实现允许您定义目标类型,那么目标类型是 SSOT 的自然选择。


推荐阅读