我有一个YAML文件,如:
%YAML 1.1
%TAG !x! tag:x.y,2013:
--- !x!1 &1
SomeThing:
member: 1
--- !x!2 &2
OtherThing:
inner: foo
我不确定它是否合规,但它是由我无法控制的程序生成的。
我真的不想把'tag:x.y,2013:1'转换成任何特定的类,所以我试着像这样使用PyYAML的BasicLoader
:
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
指令应用于流中的所有文档?
答案 0 :(得分:1)
这肯定是格式错误的YAML - YAML流中的每个文档都独立于前一个,并且可能在其上设置了不同的指令。不可否认,标准对此有点不清楚,尽管Section 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)