【问题标题】:Yml : Unable to validate load merged yml fileYml:无法验证加载合并的 yml 文件
【发布时间】: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 的情况下,错误很可能是 emailNamepasswordusername 在合并之前包含标量,但之后包含序列。订单没有问题。
  • flyx,所以即使订单发生变化,你的意思是说在验证期间不会有任何问题?
  • 非常确定。 YAML 规范禁止密钥顺序来传达内容信息,因此任何依赖于密钥顺序的验证器都违反了规范。不过我不知道你用的是哪个。
  • 您正在使用 YAML.pm 加载 YAML,错误消息是来自 YAML.pm 的语法错误,而不是验证错误。看起来您使用的是非常旧的 YAML.pm 版本,它无法加载零缩进序列。为什么使用 YAML::XS 创建文件并使用 YAML.pm 进行加载?
  • 关于订单:虽然在这种情况下订单没有问题,但如果您想保留订单,您可以尝试YAML::PP并寻找preserve。免责声明:我是作者 ;-)

标签: perl yaml


【解决方案1】:

如果没有看到Schema.yml,很难确定,但我猜它会将usernamepasswordemailName 定义为标量值。合并后,它们都是值列表。您的错误说它发生在输出文件的第 3 行,这是包含您的一个新列表的第一行。

如果您将两个散列合并在一起,那么您几乎肯定不会得到与两个原始散列相同形状的东西。因此,无论您如何合并哈希,您的架构验证几乎肯定会失败。

如果您不知道为什么要以这种方式合并这些文件以及之后您想对它们做什么,我们将无法提供更多帮助。

【讨论】:

  • 您确定如果元素的顺序发生变化...其架构验证失败?我们是否有任何现成可用的工具通过互联网从给定的 yml 文件创建模式?
  • @RAMA:你确定如果元素的顺序改变......它的模式验证失败?不,我不这么认为。而且我从来没有说过我会这样做。
  • 我想我这里的问题是缩进问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-09-18
  • 1970-01-01
  • 2011-07-26
  • 1970-01-01
  • 1970-01-01
  • 2020-10-29
  • 2023-02-07
相关资源
最近更新 更多