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'))
我有一些如下所示的服务定义:
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'))