2

我有一个 YAML 文件,例如:

%YAML 1.1
%TAG !x! tag:x.y,2013:
--- !x!1 &1
SomeThing:
  member: 1
--- !x!2 &2
OtherThing:
  inner: foo

我不确定它是否合规,但它是由我无法控制的程序生成的。

真的,我不在乎将 'tag:xy,2013:1' 转换为任何特定的类,所以我尝试BasicLoader像这样使用 PyYAML:

import yaml
import pprint

with open("file.yaml", "r") as f:
    items = yaml.load_all(f, Loader=yaml.loader.BasicLoader)
    for item in items:
        pprint.pprint(item)

PyYAML 在到达第二个文档时抛出异常。

yaml.parser.ParserError: while parsing a node
found undefined tag handle '!x!'

是否有一种简单的方法可以告诉 PyYAML 完全忽略标签前缀,或者将相同的%TAG指令应用于流中的所有文档?

4

1 回答 1

2

这绝对是格式错误的 YAML——YAML 流中的每个文档都独立于之前的文档,并且可能设置了不同的指令。诚然,标准对此有点不清楚,尽管第 9.2 节指出:“请注意,[流中的]每个文档都独立于其余文档,允许异构日志文件条目。”

看起来Parser该类具有DEFAULT_TAGS映射默认标记句柄的属性:https ://github.com/yaml/pyyaml/blob/master/lib/yaml/parser.py#L76

作为一种解决方法,您可以就地修改该 dict ( Parser.DEFAULT_TAGS[u'!x!'] = u'tag:x.y,2013'),或者,也许更好的是,将基Parser类子类化并创建自己的Loader使用解析器的类:

from yaml.parser import Parser
from yaml.reader import Reader
from yaml.scanner import Scanner
from yaml.composer import Composer
from yaml.constructor import Constructor
from yaml.resolver import Resolver

class MyWonkyParser(Parser):
    DEFAULT_TAGS = {u'!x!': u'tag:x.y,2013'}
    DEFAULT_TAGS.update(Parser.DEFAULT_TAGS)

class MyWonkyLoader(Reader, Scanner MyWonkyParser, Composer, Constructor, Resolver):
    def __init__(self, stream):
        Reader.__init__(self, stream)
        Scanner.__init__(self)
        MyWonkyParser.__init__(self)
        Composer.__init__(self)
        Constructor.__init__(self)
        Resolver.__init__(self)

像这样使用它:

yaml.load_all(stream, Loader=MyWonkyLoader)
于 2013-09-09T21:08:38.903 回答