【发布时间】:2021-04-23 14:08:44
【问题描述】:
我在以下代码的帮助下合并了两个 yml 文件。
use strict ;
use warnings FATAL => qw(all), NONFATAL => qw(exec);
use Cwd qw();
use Getopt::Long qw();
use YAML::XS qw(Load Dump);
use File::Slurp qw(read_file write_file);
use Hash::Merge qw( merge );
Hash::Merge::set_behavior('RETAINMENT_PRECEDENT');
my($IN_YAML_1,$IN_YAML_2,$OUT_YAML) = undef;
($IN_YAML_1,$IN_YAML_2,$OUT_YAML) = @ARGV;
#reading 1st yaml file
my $in_yaml_1 = read_file($IN_YAML_1, { binmode => ':raw' });
my %in_hash_1 = %{ Load $in_yaml_1 };
#reading 2nd yaml file
my $in_yaml_2 = read_file($IN_YAML_2, { binmode => ':raw' });
my %in_hash_2 = %{ Load $in_yaml_2 };
#Merge hash_1 and hash_2
my %out_hash = %{ merge( \%in_hash_1, \%in_hash_2) };
open( FH, ">$OUT_YAML" ) or die "Can't open $OUT_YAML\n";
my $out_yaml = Dump \%out_hash;
write_file($OUT_YAML, { binmode => ':raw' }, $out_yaml);
close FH;
我的 yml 文件:-
一个.yml
emailName: David
emailAddresses:
- sillymoos@cpan.org
- perltricks.com@gmail.com
credentials:
username: sillymoose
password: itsasecret
两个.yml
emailName: Pranay
emailAddresses:
- heelo@cpan.org
- test@gmail.com
credentials:
username: link
password: sanity
输出:
credentials:
password:
- itsasecret
- sanity
username:
- sillymoose
- link
emailAddresses:
- sillymoos@cpan.org
- perltricks.com@gmail.com
- heelo@cpan.org
- test@gmail.com
emailName:
- David
- Pranay
如果我们注意到合并输出中元素的顺序(emailName 排在最后)。
这里同时针对我的 yml 架构验证我的合并 yml 文件。
eval { validate(YAML::LoadFile("Schema.yml"), YAML::LoadFile("merge.yml"))
失败并出现错误:
YAML Error: Invalid element in map
Code: YAML_LOAD_ERR_BAD_MAP_ELEMENT
Line: 3
Document: 1
元素顺序的改变会导致这个问题吗?我怎样才能以相同的顺序创建我的合并 yml,即 emailName: 后跟 emailAddresses: ...etc
【问题讨论】:
-
在不了解 perl 的情况下,错误很可能是
emailName、password和username在合并之前包含标量,但之后包含序列。订单没有问题。 -
flyx,所以即使订单发生变化,你的意思是说在验证期间不会有任何问题?
-
非常确定。 YAML 规范禁止密钥顺序来传达内容信息,因此任何依赖于密钥顺序的验证器都违反了规范。不过我不知道你用的是哪个。
-
您正在使用 YAML.pm 加载 YAML,错误消息是来自 YAML.pm 的语法错误,而不是验证错误。看起来您使用的是非常旧的 YAML.pm 版本,它无法加载零缩进序列。为什么使用 YAML::XS 创建文件并使用 YAML.pm 进行加载?
-
关于订单:虽然在这种情况下订单没有问题,但如果您想保留订单,您可以尝试YAML::PP并寻找
preserve。免责声明:我是作者 ;-)