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'要素で最大値を見つける1行は何ですか?

私は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";

より醜く、理解しにくく、編集するのが難しい1行バージョン:

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>パスに含まれていると仮定します。そうでない場合は、findnodes()実際のデータに合わせて関数呼び出しのxpathを調整してください。

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

関連情報