且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

如何解析包含多个文档的 YAML 文件?

更新时间:2023-02-23 16:36:56

该错误消息非常具体,文档需要以 文档开始标记.您的第一个文档没有这样的标记,尽管它有一个文档结束标记.在你用 ... 明确结束第一个文档后,你不能再在 PyYAML 中使用没有文档边界标记的文档,你必须明确地用 --- 开始它:

The error message is quite specific that a document needs to start with a document start marker. Your first document doesn't have such a marker, although it has a document end marker. After you explicitly end the first document with ... you can no longer use a document without document boundary markers in PyYAML, you explicitly have to start it with ---:

文件的结尾应如下所示:

The end of your file should look like:

    kind: UndergroundDistributionLineSegment
...
---
ingests:
  - timestamp: 1970-01-01T00:00:00.000Z
    id: OverheadDistributionLineSegment_31168454

您可以从第一个文档中省略显式文档开始标记,但您需要为每个后续文档包含一个开始标记.文档结束标记是可选的.

You can leave out the explicit document start marker from the first document, but you need to include a start marker for every following document. Document end markers are optional.

如果您不能完全控制输入,使用 .load_all() 是不安全的.通常没有理由冒险,您应该使用 .safe_load_all() 并扩展 SafeLoader 来处理您的 YAML 可能包含的任何特定标签.

If you don't have complete control over the input, using .load_all() is not safe. There normally is no reason to take that risk and you should be using .safe_load_all() and extend the SafeLoader to handle any specific tags that your YAML might contain.

除此之外,您应该使用明确的版本指令开始您的 YAML 文档在文档开始指示符之前(您还应该将其添加到第一个文档):

Apart from that you should start your YAML documents with an explicit version directive before the document start indicator (which you should also add to the first document):

%YAML 1.1
---

这是为了您的 YAML 文件的未来编辑者的利益,因为您使用的是 PyYAML,它仅支持(大部分)YAML 1.1 而不是 YAML 1.2 规范(2009 年表格).替代方案当然是将您的 YAML 解析器升级到例如 ruamel.yaml,这将还警告您使用不安全的 load_all()(免责声明:我是该解析器的作者).ruamel.yaml 不允许您在显式文档结束标记(如@flyx 指出的那样)之后拥有一个裸文档,这是一个 错误.

This is for the benefit of future editors of your YAML files, because you are using PyYAML, which only supports (most of) YAML 1.1 and not the YAML 1.2 specification (form 2009). The alternative is of course to upgrade your YAML parser to e.g ruamel.yaml, which would also have warned you about your use of the unsafe load_all() (disclaimer: I am the author of that parser). ruamel.yaml doesn't allow you to have a bare document after an explicit end-of-document marker (which is allowed as @flyx pointed out), which is a bug.