Symfony YAML 格式转换

Symfony YAML format conversion

我有一些如下所示的服务定义:

MyService:
    class: Some\Class\Here
    factory:
        - SomeFactoryHere
        - method
    calls:
        - [add, ["@=service('AnotherService1').create(service('AnotherService2'), service('AnotherService3'), service('AnotherService3'))"]]

恕我直言,如果将其转换为如下内容,可读性会更好:

MyService:
    class: Some\Class\Here
    factory:
        - SomeFactoryHere
        - method
    calls:
        -
          add,
          "@=service('AnotherService1').create(
              service('AnotherService2'),
              service('AnotherService3'),
              service('AnotherService3')
          )"

但是,这不是有效的 YAML(Symfony 解析器失败),我的问题是如何将此配置转换为上述配置?

UPD#1

看看 - 那里有重要的细微差别。

你写的是有效的 YAML。如果 Symfony 解析器失败,它有一个错误。但是无论如何,第二个YAML并不代表与第一个YAML相同的结构。

在第一个 YAML 中,calls 是一个序列。 calls 的第一个序列项也是一个序列,其中包含标量 add 和另一个序列。在第二个 YAML 中,calls 也是一个序列,但它包含的项是一个标量,包含从 add,)" 的所有内容。逗号在这里是内容,因为您没有启动流程序列([)。这是块式 YAML,相当于第一个 YAML:

MyService:
    class: Some\Class\Here
    factory:
        - SomeFactoryHere
        - method
    calls:
        - - add
          - - "@=service('AnotherService1').create(\
                 service('AnotherService2'),
                 service('AnotherService3'),
                 service('AnotherService3')\
              )"

字符串行末尾的反斜杠导致没有插入白色space。默认情况下,YAML 在它遇到的双引号字符串中为每个换行符插入一个 space 字符。此 YAML 标量生成的字符串与您的第一个 YAML 包含的字符串完全相同。

- - 是紧凑型,它同时启动两个嵌套的序列项。所以现在,calls 又是一个序列,其中一个序列作为第一项。该嵌套序列包含一个标量 add 作为第一项,另一个序列作为第二项。该序列包含双引号标量。

分解字符串的最佳方法

"@=service('AnotherService1').create(service('AnotherService2'), service('AnotherService3'), service('AnotherService3'))"

是通过使用剥离的 folded block scalar。这样做的限制是你不能用反斜杠转义任何特殊字符,但你的例子中没有这些字符(你需要 "" 围绕你的标量的原因是因为它以 @ 开头,这是一个保留字符)。

然后您还必须正确地重新表示您拥有的结构,正如@flyx 已经指出的那样:calls 的值是一个序列,其第一个元素是标量列表 add 和由上述长标量组成的序列,为了便于阅读,您希望将其拆分:

import yaml

yaml_str = """\
MyService:
    class: Some\Class\Here
    factory:
        - SomeFactoryHere
        - method
    calls:
        - - add
          - - >-
              @=service('AnotherService1').create(
              service('AnotherService2'),
              service('AnotherService3'),
              service('AnotherService3'))
"""

data = yaml.safe_load(yaml_str)
print(data)

给出:

"@=service('AnotherService1').create( service('AnotherService2'), service('AnotherService3'), service('AnotherService3'))"

请注意,这会在 .create(service( 之间提供一个额外的 space。

Symphony 使用的 YAML 解析器似乎无法解析上述内容(尽管它是正确的)。您也可以尝试:

MyService:
    class: Some\Class\Here
    factory:
        - SomeFactoryHere
        - method
    calls:
        - 
          - add
          - 
            - >-
              @=service('AnotherService1').create(
              service('AnotherService2'),
              service('AnotherService3'),
              service('AnotherService3'))