如何使用 Perl oneliner 从特定 XML 元素中查找最大值?

如何使用 Perl oneliner 从特定 XML 元素中查找最大值?

我有一个具有以下语法的 XML 文件

<element>
  <id>0</id>
  <tag1>something</tag1>
  ...
  <tagn>something</tagn>
</element>
<element>
  <id>1</id>
  <tag1>something</tag1>
  ...
  <tagn>something</tagn>
</element>

什么 Perl 单行代码会从 'id' 元素中找到最大值?

我是 Perl 新手,但是,我知道我可以通过执行以下操作来获取 id 元素的值:

perl -wne 'print $1 if /<id>(\d+)<\/id>/'

它产生“0123456789”(一个只有数字的字符串?)。

基于这个答案https://unix.stackexchange.com/a/130903/374251我可以尝试将匹配项存储在列表中并打印列表中的最大值。但是,我不知道如何在一句话中做到这一点。

答案1

独立的 perl 脚本:

#!/usr/bin/perl

use strict;
use XML::LibXML;
use List::Util qw(max);

my $filename = './input.xml';
my $dom = XML::LibXML->load_xml(location => $filename);

my @ids = map { $_->to_literal() } $dom->findnodes('/data/element/id');

print max(@ids), "\n";

更丑陋、更难理解、更难编辑的单行版本:

perl -MXML::LibXML -MList::Util=max -e '
  $dom = XML::LibXML->load_xml(location => shift);
  @ids = map { $_->to_literal() } $dom->findnodes("/data/element/id");
  print max(@ids), "\n";' input.xml

注意:以上两者都假设<element>s 包装在<data>路径内。如果不是,请调整函数调用中的 xpathfindnodes()以适合您的实际数据。

我使用以下input.xml文件运行它们:

<?xml version='1.0' encoding='UTF-8'?>
<data>
<element>
  <id>0</id>
  <tag1>something</tag1>
  <tagn>something</tagn>
</element>
<element>
  <id>1</id>
  <tag1>something</tag1>
  <tagn>something</tagn>
</element>
<element>
  <id>2</id>
  <tag1>something</tag1>
  <tagn>something</tagn>
</element>
<element>
  <id>3</id>
  <tag1>something</tag1>
  <tagn>something</tagn>
</element>
<element>
  <id>4</id>
  <tag1>something</tag1>
  <tagn>something</tagn>
</element>
<element>
  <id>5</id>
  <tag1>something</tag1>
  <tagn>something</tagn>
</element>
</data>

两者都得到了正确的结果 5。


location => $filename顺便说一句,通过将行更改为或 ,可以使任一版本读取 STDIN location => shift

my $dom = XML::LibXML->load_xml(IO => *STDIN);

my在没有 的单行版本中 是可选的,use strict但在独立版本中是必需的。


顺便说一句,修改任一脚本也很容易,以便可以在命令行上指定输入文件名和 xpath。这样您就有了一个通用工具来获取max()任何 xpath 元素的值。例如

#!/usr/bin/perl

use strict;
use XML::LibXML;
use List::Util qw(max);

my $dom = XML::LibXML->load_xml(location => shift);
my @ids = map { $_->to_literal() } $dom->findnodes(shift);
print max(@ids), "\n";

运行为,例如

$ xml-max.pl input.xml /data/element/id
5

相关内容