在for循环中解析yaml文件并创建新的yaml文件非特定标记Python

2024-05-23 16:55:37 发布

您现在位置:Python中文网/ 问答频道 /正文

大家好,我想加载一个yaml文件,解析它并为每个非特定标记(!元素)创建新的yaml文件

我要把每一个部分都剪下来!新yaml文件示例中的元素

新建文件夹/element1/element1\u config.yml

内容应仅为:

    name: element1
    gnc_script:
      - '*fcc_cores_1'
      - '*setup'
    relationship:
      - projectx
      - projectxy
      - projectxyt
      # indirect related on
      - projectxyz1

我的yaml看起来是这样的(我原来的yml非常大,有100多个元素,所以对于这个问题,我使用了一个较短的版本):

elements:
  - !Element
    name: element1
    gnc_script:
      - '*fcc_cores_1'
      - '*setup'
    relationship:
      - projectx
      - projectxy
      - projectxyt
      # indirect related on
      - projectxyz1

  - !Element
    name: element2
    gnc_script:
      - '*fcc_cores_1'
    relationship:
      - projectx
      - projectxy
      - projectxyt
      # indirect related on
      - projectxyz1

  - !Element
    name: element3
    gnc_script:
      - '*fcc_cores_1'
      - '*setup'
    relationship:
      - projectx
      - projectxy
      - projectxyt
      # indirect related on
      - projectxyz1

你知道我怎么解决吗

到目前为止,我所拥有的:

import yaml


with open ('elements.yml', 'r') as elements_file:
    elements_yml = yaml.load(elements_file)

elements= elements_yml["elements"]["!Element"]

for element in elements:
   os.makedirs(elements_yml["elements"]["!Element"]["name"])

   # create new yaml file with content of element

Tags: nameyamlymlscriptelementselementcoresindirect
1条回答
网友
1楼 · 发布于 2024-05-23 16:55:37

如果希望处理YAML文件的结构而不关心其内容,则不需要构造本机Python对象。相反,请使用节点图:

import yaml, sys
from yaml.nodes import SequenceNode, MappingNode
from yaml.resolver import BaseResolver

input = """
elements:
  - !Element
    name: element1
    gnc_script:
      - '*fcc_cores_1'
      - '*setup'
    relationship:
      - projectx
      - projectxy
      - projectxyt
      # indirect related on
      - projectxyz1

  - !Element
    name: element2
    gnc_script:
      - '*fcc_cores_1'
    relationship:
      - projectx
      - projectxy
      - projectxyt
      # indirect related on
      - projectxyz1

  - !Element
    name: element3
    gnc_script:
      - '*fcc_cores_1'
      - '*setup'
    relationship:
      - projectx
      - projectxy
      - projectxyt
      # indirect related on
      - projectxyz1
"""

node = yaml.compose(input)

visited = set()

def output(node):
  yaml.serialize(node, sys.stdout)
  sys.stdout.write("...\n")

def visit(node):
  if node in visited: return
  if node.tag == "!Element":
    node.tag = BaseResolver.DEFAULT_MAPPING_TAG
    output(node)
  visited.add(node)
  if isinstance(node, SequenceNode):
    for child in node.value:
      visit(child)
  elif isinstance(node, MappingNode):
    for k,v in node.value:
      visit(k); visit(v)

visit(node)

这将产生:

name: element1
gnc_script:
- '*fcc_cores_1'
- '*setup'
relationship:
- projectx
- projectxy
- projectxyt
- projectxyz1
...
name: element2
gnc_script:
- '*fcc_cores_1'
relationship:
- projectx
- projectxy
- projectxyt
- projectxyz1
...
name: element3
gnc_script:
- '*fcc_cores_1'
- '*setup'
relationship:
- projectx
- projectxy
- projectxyt
- projectxyz1
...

该代码包括其输入和输出到stdout,用于演示;只需重写output(node)即可创建所需文件,并将输入替换为所需处理的文件。例如,这会将它们写入单独的文件中;需要元素中键name的现有标量值:

def output(node):
  name = next(x[1].value for x in node.value if x[0].value == "name")
  with open("{0}.yaml".format(name), "w") as f:
    yaml.serialize(node, f)

如您所见,输入中的注释不是输出的一部分。这是因为它们被PyYAML的解析器丢弃了。用Pyaml解决这个问题没有简单的方法;您可以尝试ruamel,它试图保留注释,但我不知道它的API

相关问题 更多 >