database.yml 上的 Yaml 到 JSON 的转换会跳过一些特殊功能
Yaml to JSON conversion on database.yml skips some special functionality
正在尝试将 about yml 转换为 json。当我尝试这样做时,它会跳过 &、<<、*。我尝试了很多东西,但它似乎没有像我预期的那样创建 json。
我正在尝试使用节点将 yml 转换为 json,反之亦然。
development-mysql: &development-mysql
pool: 5
encoding: utf8
host: 127.0.0.1
port: 1234
alpha: &alpha
<<: *development-mysql
adapter: oracle
database: testDB
username: test
time_zone: UTC
转换为
{
"development-mysql": {
"pool": 5,
"encoding": "utf8",
"host": "127.0.0.1",
"port": 1234
},
"alpha": {
"pool": 5,
"encoding": "utf8",
"host": "127.0.0.1",
"port": 1234,
"adapter": "oracle",
"database": "testDB",
"username": "test",
"time_zone": "UTC"
}
}
当我尝试将它转换回 yml 时是这样的
development-mysql:
pool: 5
encoding: utf8
host: 127.0.0.1
port: 1234
alpha:
pool: 5
encoding: utf8
host: 127.0.0.1
port: 1234
adapter: oracle
database: testDB
username: test
time_zone: UTC
现在理论上这是正确的,但我们有点失去了 <<,* 和 & 的能力。保留所有功能的 json 并将其转换回 yml
的任何方法
当您使用锚点和别名 (&
/ *
) 或合并键 (<<
) 时,YAML 规范中甚至没有定义,但作为optional extension,您正在使用 JSON.
中根本不存在的功能
合并键类型 (<<
) 甚至被定义为 merging 映射,这意味着如果您使用此功能加载文档,即使您编写它返回 YAML,您将打印出合并的地图,因为它是在加载文档时处理的。您只能通过使用实际上不处理合并密钥的实现来规避此问题(并非全部)。
对于锚点和别名,简单的事实是 JSON 不提供类似的东西。这意味着如果您将一个值序列化为 JSON,其中任何子节点被多次引用,JSON 实现别无选择,只能复制该值。
现在当然有办法了。补救措施是将 YAML 输入的 structure(而不是构造值)序列化为 JSON。让我们看一下这个简单的 YAML 示例:
- &a foo
- *a
结果 JSON 可能如下所示:
{
"type": "sequence",
"items": [
{
"type": "scalar",
"anchor": "a",
"value": "foo"
}, {
"type": "alias",
"target": "a"
}
]
}
此 JSON 表示保留了原始 YAML 文件的所有信息,因此可以从中重建 YAML 输入。但是 JSON 变得很拥挤,因为我们需要将 YAML 输入的结构信息编码到对象中。问题是 JSON 是否对您尝试用它做的任何事情有用。
如果这是可行的方法,您将需要实施它。首先,您需要一个 YAML 实现,让您可以根据 YAML 规范访问低级事件树(并非所有人都这样做),请参见此图:
(来源:yaml.org)
所谓的事件树,在大多数实现中,实际上是一个事件列表,由StartSequence、EndSequence 等。您需要编写代码将此列表编码为 JSON,还需要编写代码将 JSON 解码回列表,然后您可以将其填回YAML 实现以获得您想要的结果。
现在很可能这对于您实际想要做的事情来说太费力了。我强烈建议不要这样做,并在不将 YAML 转换为 JSON 的情况下找到一种方法来处理您要解决的任何问题,同时要求它保留 JSON.
中缺少的 YAML 功能
正在尝试将 about yml 转换为 json。当我尝试这样做时,它会跳过 &、<<、*。我尝试了很多东西,但它似乎没有像我预期的那样创建 json。
我正在尝试使用节点将 yml 转换为 json,反之亦然。
development-mysql: &development-mysql
pool: 5
encoding: utf8
host: 127.0.0.1
port: 1234
alpha: &alpha
<<: *development-mysql
adapter: oracle
database: testDB
username: test
time_zone: UTC
转换为
{
"development-mysql": {
"pool": 5,
"encoding": "utf8",
"host": "127.0.0.1",
"port": 1234
},
"alpha": {
"pool": 5,
"encoding": "utf8",
"host": "127.0.0.1",
"port": 1234,
"adapter": "oracle",
"database": "testDB",
"username": "test",
"time_zone": "UTC"
}
}
当我尝试将它转换回 yml 时是这样的
development-mysql:
pool: 5
encoding: utf8
host: 127.0.0.1
port: 1234
alpha:
pool: 5
encoding: utf8
host: 127.0.0.1
port: 1234
adapter: oracle
database: testDB
username: test
time_zone: UTC
现在理论上这是正确的,但我们有点失去了 <<,* 和 & 的能力。保留所有功能的 json 并将其转换回 yml
的任何方法当您使用锚点和别名 (&
/ *
) 或合并键 (<<
) 时,YAML 规范中甚至没有定义,但作为optional extension,您正在使用 JSON.
合并键类型 (<<
) 甚至被定义为 merging 映射,这意味着如果您使用此功能加载文档,即使您编写它返回 YAML,您将打印出合并的地图,因为它是在加载文档时处理的。您只能通过使用实际上不处理合并密钥的实现来规避此问题(并非全部)。
对于锚点和别名,简单的事实是 JSON 不提供类似的东西。这意味着如果您将一个值序列化为 JSON,其中任何子节点被多次引用,JSON 实现别无选择,只能复制该值。
现在当然有办法了。补救措施是将 YAML 输入的 structure(而不是构造值)序列化为 JSON。让我们看一下这个简单的 YAML 示例:
- &a foo
- *a
结果 JSON 可能如下所示:
{
"type": "sequence",
"items": [
{
"type": "scalar",
"anchor": "a",
"value": "foo"
}, {
"type": "alias",
"target": "a"
}
]
}
此 JSON 表示保留了原始 YAML 文件的所有信息,因此可以从中重建 YAML 输入。但是 JSON 变得很拥挤,因为我们需要将 YAML 输入的结构信息编码到对象中。问题是 JSON 是否对您尝试用它做的任何事情有用。
如果这是可行的方法,您将需要实施它。首先,您需要一个 YAML 实现,让您可以根据 YAML 规范访问低级事件树(并非所有人都这样做),请参见此图:
(来源:yaml.org)
所谓的事件树,在大多数实现中,实际上是一个事件列表,由StartSequence、EndSequence 等。您需要编写代码将此列表编码为 JSON,还需要编写代码将 JSON 解码回列表,然后您可以将其填回YAML 实现以获得您想要的结果。
现在很可能这对于您实际想要做的事情来说太费力了。我强烈建议不要这样做,并在不将 YAML 转换为 JSON 的情况下找到一种方法来处理您要解决的任何问题,同时要求它保留 JSON.
中缺少的 YAML 功能