保留 YAML 顺序 perl

发布于 2024-12-01 12:15:48 字数 431 浏览 2 评论 0原文

我想从 YAML 文件读取数据,但需要保留元素的顺序。
perl 中是否有具有此功能的模块以及如何做到这一点?


回应 @mugen kenichi

我设法做我想做的事,但我不相信这是一个合理的解决方案。

旧 YAML:

foo:
   bar: some value
   baz: other value
qwe:
   bar: yet another value
   baz: again

新 YAML

 -
   foo:
      bar: some value
      baz: other value
 -  
   qwe:
      bar: yet another value
      baz: again

I want to read data from a YAML file but I need the order of the elements to be preserved.

Is there a module in perl which has this functionality and how to do that?


In response to @mugen kenichi

I managed to do what I want but I don't believe that this is a reasonable solution.

old YAML:

foo:
   bar: some value
   baz: other value
qwe:
   bar: yet another value
   baz: again

new YAML

 -
   foo:
      bar: some value
      baz: other value
 -  
   qwe:
      bar: yet another value
      baz: again

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

甜中书 2024-12-08 12:15:48

更新 YAML.pm 现在支持订单保存。请参阅此最新答案

YAML 规范明确指出“映射键没有order”以及“在节点顺序很重要的每种情况下,必须使用序列”。从映射推断顺序将违反规范。正如 mugen 提到的,使用有序映射是保持顺序的正确解决方案。


If you *really* wanted to, you could somehow get a YAML parser to dump into a [Tie::IxHash][2] which will preserve order... but I know of no Perl YAML parser which gives you that level of control. It's possible you could do something with [YAML::Old::Loader][3], but that is not a very good YAML parser and YAML::Old::Loader is not documented.

第三种选择是使用显式 YAML 标记(又名类型)指示解析器将您的映射加载为特殊类型,然后您提供回调...但即使如此,YAML 解析器也可能会为您的回调提供无序哈希。

我建议您只需更改 YAML。可移植数据语言的要点在于,所有语义在数据文件或规范中都是明确的,而不是在特定解析器中隐含的。有序映射是一种公认​​的、紧凑的 YAML 习惯用法。

- foo:
      bar: some value
      baz: other value
- qwe:
      bar: yet another value
      baz: again

UPDATE: YAML.pm now supports order preservation. See this up-to-date answer.

The YAML spec specifically states that "mapping keys do not have an order" and that "in every case where node order is significant, a sequence must be used". To infer order from a mapping would be in violation of the spec. Using ordered mappings, as mentioned by mugen, is the correct solution to preserve order.


If you *really* wanted to, you could somehow get a YAML parser to dump into a [Tie::IxHash][2] which will preserve order... but I know of no Perl YAML parser which gives you that level of control. It's possible you could do something with [YAML::Old::Loader][3], but that is not a very good YAML parser and YAML::Old::Loader is not documented.

A third option would be to use explicit YAML tags (aka types) to instruct the parser to load your mappings as a special type and then you supply the callback... but even then it's likely the YAML parser will supply your callback with an unordered hash.

I would suggest you simply change the YAML. The point of a portable data language is that all the semantic meaning is explicit in the data file or the spec, not implicit in a particular parser. Ordered mappings are an accepted, compact YAML idiom.

- foo:
      bar: some value
      baz: other value
- qwe:
      bar: yet another value
      baz: again
橘味果▽酱 2024-12-08 12:15:48

从版本 0.021 开始,可以使用 YAML::PP

use YAML::PP;
use YAML::PP::Common qw/ :PRESERVE /;
my $yp = YAML::PP->new( preserve => PRESERVE_ORDER );
my $data = $yp->load_string($yaml);
say $yp->dump_string($data);

(免责声明:我是该模块的作者)

It is possible with YAML::PP since version 0.021.

use YAML::PP;
use YAML::PP::Common qw/ :PRESERVE /;
my $yp = YAML::PP->new( preserve => PRESERVE_ORDER );
my $data = $yp->load_string($yaml);
say $yp->dump_string($data);

(Disclaimer: I'm the module's author)

沫尐诺 2024-12-08 12:15:48

虽然需要一些搜索,但这是可能的。基于 https://metacpan.org/pod/YAML::PP#preserve,我得到了这个简短的脚本来读取第一个文件并在 STDOUT 上打印出 YAML。 Data:Dumper也显示订单保持不变。

#!/usr/bin/perl -w
use strict;

use YAML::PP;
use YAML::PP::Common;
my $yp = YAML::PP->new( preserve => YAML::PP::Common->PRESERVE_ORDER );
my $yaml = $yp->load_file( $ARGV[0] );
print $yp->dump($yaml), "\n";

It took some searching, but it is possible. Based on https://metacpan.org/pod/YAML::PP#preserve, I got this short script to read in the first file and print out the YAML on STDOUT. Data:Dumper also shows that the order is maintained.

#!/usr/bin/perl -w
use strict;

use YAML::PP;
use YAML::PP::Common;
my $yp = YAML::PP->new( preserve => YAML::PP::Common->PRESERVE_ORDER );
my $yaml = $yp->load_file( $ARGV[0] );
print $yp->dump($yaml), "\n";
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文