我有一个具有以下语法的 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