假设我有一个YAML文件,如下所示:
template:
artifacts:
config:
a: value1
b: value2
jars:
a: value1
b: value2
scripts:
a: value1
b: value2
我希望它像一棵树,如下所示:
template--
|__artifacts__
|__config__
| |__a__
| | |__value1
| |
| |__b__
| |__value2
|__jars__ ...
我该怎么做?
答案 0 :(得分:1)
有多个适用于Python的YAML解析器,但唯一
一个支持最新的YAML规范(2009年发布的1.2)
是ruamel.yaml(免责声明:
我是该软件包的作者)。其他软件包(PySyck,PyYAML)
也不支持加载有效的YAML构造,例如
序列/映射作为映射键。 ruamel.yaml
可以定向到
为那些仅支持YAML 1.1的过时软件包转储YAML 1.1
版本的YAML规范。
嵌套的Python dict
可以用作树结构,其键为a
节点的值和非dict
叶节点的值。这是
从YAML文件中的映射加载的数据结构。
from pathlib import Path
from pprint import pprint
import ruamel.yaml
input = Path('input.yaml')
yaml = ruamel.yaml.YAML()
data = yaml.load(input)
pprint(data)
给出:
{'template': {'artifacts': {'config': {'a': 'value1',
'b': 'value2'},
'jars': {'a': 'value1',
'b': 'value2'},
'scripts': {'a': 'value1',
'b': 'value2'}}}}
这看起来不像您的预期输出,字典也不是真正的树状结构。
当然,您可以遍历data
-结构并创建Node
s的树,但是
这有点落后,因为您可以告诉解析器直接创建一个Node
在建造树时。
import sys
from ruamel.yaml.constructor import SafeConstructor
class Node:
# your node definition here
pass
class MyConstructor(SafeConstructor):
def construct_yaml_map(self, node):
data = Node()
yield data
res = self.construct_mapping(node)
# and update data with the parsed data
MyConstructor.add_constructor('tag:yaml.org,2002:map',
MyConstructor.construct_yaml_map)
yaml = ruamel.yaml.YAML()
yaml.Constructor = MyConstructor
data = yaml.load(input)
请注意,以上内容会自动处理YAML文件中的递归结构, 当以正常方式加载YAML时,有些事情不容易实现。