XML::LibXML::Simpleを使ってみる

XMLファイルを読み込んで、マップ形式で表示してみる。
ソースコードは以下の通り

use strict;
use warnings;
use utf8;
use IO::File;
use XML::LibXML::Simple;
use Data::Dumper;

binmode STDIN, ':utf8';
binmode STDOUT, ':utf8';
binmode STDERR, ':utf8';

# Input Check
if (@ARGV != 1) {
  print STDERR "Please input XML file name.\n";
  exit 1;
}

my $xmlin_name = $ARGV[0];

# File Check
unless (-f $xmlin_name) {
  print STDERR "$xmlin_name is not found.\n";
  exit 1;
}

# Input XML
my $fh = IO::File->new($xmlin_name, 'r');
my $xml_parser = XML::LibXML::Simple->new();
my $xml = $xml_parser->XMLin($fh, KeepRoot => 1, ForceArray => 1, ForceContent => 1);

$fh->close;

print Dumper($xml);

my $persons = $xml->{'addressBook'}[0]{'person'};

# Output XML Data
for (my $cnt = 0; $cnt < @$persons; $cnt++) {
  print '(' . ($cnt + 1) . ')' . "\n";
  foreach my $key (sort keys %{$persons->[$cnt]}) {
    print "\t" . $key . ' : ' . $persons->[$cnt]{$key}[0]{'content'} . "\n";
  }
}

exit 0;

XMLファイル(sample.xml)

<?xml version="1.0" encoding="UTF-8"?>
<addressBook>
  <person>
    <name>山田 太郎</name>
    <email>taro.yamada@xxx.com</email>
    <address>東京</address>
  </person>
  <person>
    <name>田中 次郎</name>
    <email>jiro.tanaka@xxx.com</email>
    <address>大阪</address>
  </person>
  <person>
    <name>阿部 三郎</name>
    <email>saburo.abe@xxx.com</email>
    <address>名古屋</address>
  </person>
</addressBook>

実行結果(念のため、読み込んだ直後のデータをDumpする。)

$ perl input_xml_simple.pl sample.xml
$VAR1 = {
          'addressBook' => [
                           {
                             'person' => [
                                         {
                                           'email' => [
                                                      {
                                                        'content' => 'taro.yamada@xxx.com'
                                                      }
                                                    ],
                                           'name' => [
                                                     {
                                                       'content' => "\x{5c71}\x{7530} \x{592a}\x{90ce}"
                                                     }
                                                   ],
                                           'address' => [
                                                        {
                                                          'content' => "\x{6771}\x{4eac}"
                                                        }
                                                      ]
                                         },
                                         {
                                           'email' => [
                                                      {
                                                        'content' => 'jiro.tanaka@xxx.com'
                                                      }
                                                    ],
                                           'name' => [
                                                     {
                                                       'content' => "\x{7530}\x{4e2d} \x{6b21}\x{90ce}"
                                                     }
                                                   ],
                                           'address' => [
                                                        {
                                                          'content' => "\x{5927}\x{962a}"
                                                        }
                                                      ]
                                         },
                                         {
                                           'email' => [
                                                      {
                                                        'content' => 'saburo.abe@xxx.com'
                                                      }
                                                    ],
                                           'name' => [
                                                     {
                                                       'content' => "\x{963f}\x{90e8} \x{4e09}\x{90ce}"
                                                     }
                                                   ],
                                           'address' => [
                                                        {
                                                          'content' => "\x{540d}\x{53e4}\x{5c4b}"
                                                        }
                                                      ]
                                         }
                                       ]
                           }
                         ]
        };
(1)
	address : 東京
	email : taro.yamada@xxx.com
	name : 山田 太郎
(2)
	address : 大阪
	email : jiro.tanaka@xxx.com
	name : 田中 次郎
(3)
	address : 名古屋
	email : saburo.abe@xxx.com
	name : 阿部 三郎
$

DOMではなくマップとリストで管理できるのは楽かも知れない。
personタグに囲まれた要素(name,email,address)の順番が保持できないのが難点か。

PerlでXMLの扱いを学ぶための自作ドリル

モジュールはXML::LibXMLを使用。

問題

XML書き出しスクリプト

name, email, addressを入力して、XMLでファイルに書き出す。(項目名はプロンプトとして表示する。)
実行結果

$ perl output_xml.pl
name : 山田太郎(改行)
email : taro.yamada@xxx.com(改行)
address : 東京(改行)
name : 田中次郎(改行)
email : jiro.tanaka@yyy.com(改行)
address : 大阪(改行)
name : 阿部三郎(改行)
email : saburo.abe@zzz.com(改行)
address : 名古屋(改行)
name : (Ctrl+Dで終了)
$

書き出し結果ファイル(output_xxxxxxxxxx.xml)

<?xml version="1.0" encoding="UTF-8"?>
<addressBook>
  <person>
    <name>山田太郎</name>
    <email>taro.yamada@xxx.com</email>
    <address>東京</address>
  </person>
  <person>
    <name>田中次郎</name>
    <email>jiro.tanaka@yyy.com</email>
    <address>大阪</address>
  </person>
  <person>
    <name>阿部三郎</name>
    <email>saburo.abe@zzz.com</email>
    <address>名古屋</address>
  </person>
</addressBook>
XML読み込みスクリプト

XMLファイルを読み込み、マップ形式で画面に表示する。
読み込みファイル(output_xxxxxxxxxx.xml)

<?xml version="1.0" encoding="UTF-8"?>
<addressBook>
  <person>
    <name>山田太郎</name>
    <email>taro.yamada@xxx.com</email>
    <address>東京</address>
  </person>
  <person>
    <name>田中次郎</name>
    <email>jiro.tanaka@yyy.com</email>
    <address>大阪</address>
  </person>
  <person>
    <name>阿部三郎</name>
    <email>saburo.abe@zzz.com</email>
    <address>名古屋</address>
  </person>
</addressBook>

実行結果

$ perl input_xml.pl output_xxxxxxxxxx.xml
(1)
	name : 山田太郎
	email : taro.yamada@xxx.com
	address : 東京
(2)
	name : 田中次郎
	email : jiro.tanaka@yyy.com
	address : 大阪
(3)
	name : 阿部三郎
	email : saburo.abe@zzz.com
	address : 名古屋
$
続きを読む

PerlでCSVの読み書きを学ぶための自作ドリル

CSVを扱うと同時に、パッケージモジュールの扱いにも慣れさせるための問題と解答例。
モジュールはText::CSV_XSを使用。

問題

CSV書き出しスクリプト

name, email, addressを入力して、CSVでファイルに書き出す。(項目名はプロンプトとして表示する。)
実行結果

$ perl output_csv.pl
name : Taro Yamada(改行)
email : taro.yamada@xxx.com(改行)
address : tokyo(改行)
name : Jiro Tanaka(改行)
email : jiro.tanaka@xxx.com(改行)
address : osaka(改行)
name : Saburo Abe(改行)
email : saburo.abe@xxx.com(改行)
address : nagoya(改行)
name : (Ctrl+Dで終了)
$

書き出し結果ファイル(output_xxxxxxxxxx.csv)

name,email,address
"Taro Yamada",taro.yamada@xxx.com,tokyo
"Jiro Tanaka",jiro.tanaka@xxx.com,osaka
"Saburo Abe",saburo.abe@xxx.com,nagoya
CSV読み込みスクリプト

CSVファイルを読み込み、マップ形式で画面に表示する。
読み込みファイル(output_xxxxxxxxxx.csv)

name,email,address
"Taro Yamada",taro.yamada@xxx.com,tokyo
"Jiro Tanaka",jiro.tanaka@xxx.com,osaka
"Saburo Abe",saburo.abe@xxx.com,nagoya

実行結果

$ perl input_csv.pl output_xxxxxxxxxx.csv
(1)
	name : Taro Yamada
	email : taro.yamada@xxx.com
	address : tokyo
(2)
	name : Jiro Tanaka
	email : jiro.tanaka@xxx.com
	address : osaka
(3)
	name : Saburo Abe
	email : saburo.abe@xxx.com
	address : nagoya
$
続きを読む

Perlで文字列操作を学ぶための自作ドリル(日本語仮名変換)

こちらは日本語文字列(ひらがな/カタカナ)を扱う処理。

問題

ひらがな→カタカナ(キー入力→画面出力)

実行結果

$ perl kana_h2k.pl
あいうえお カキクケコ(改行)
アイウエオ カキクケコ
さシすセそ タちツてト(改行)
サシスセソ タチツテト
(Crtl+Dで終了)$
カタカナ→ひらがな(キー入力→画面出力)

実行結果

$ perl kana_k2h.pl
あいうえお カキクケコ(改行)
あいうえお かきくけこ
さシすセそ タちツてト(改行)
さしすせそ たちつてと
(Crtl+Dで終了)$
ひらがな⇔カタカナ(キー入力→画面出力)

実行結果

$ perl kana_swap.pl
あいうえお カキクケコ(改行)
アイウエオ かきくけこ
さシすセそ タちツてト(改行)
サしスせソ たチつテと
(Crtl+Dで終了)$
ひらがな⇔カタカナ(ファイル入出力&コード自動判別)

実行結果

$ perl kana_swap_textconv.pl kana_src.txt kana_res.txt

変換元ファイル(kana_src.txt) (文字コードはUTF8,CP932,EUC-JPを用意)

あいうえお アイウエオ
カキクケコ かきくけこ
さしすせそ サシスセソ
タチツテト たちつてと
なにぬねの ナニヌネノ
ハヒフヘホ はひふへほ
まミむメも マみムめモ
ヤ ゆ ヨ や ユ よ
らリるレろ ラりルれロ
ワ を ン わ ヲ ん
ぁぃぅぇぉ ァィゥェォ
ッャュョ  っゃゅょ 
がぎぐげご ガギグゲゴ
ザジズゼゾ ざじずぜぞ
だぢづでど ダヂヅデド
バビブベボ ばびぶべぼ
ぱぴぷぺぽ パピプペポ

変換結果ファイル(kana_res.txt) (文字コードは変換元ファイルと同じ)

アイウエオ あいうえお
かきくけこ カキクケコ
サシスセソ さしすせそ
たちつてと タチツテト
ナニヌネノ なにぬねの
はひふへほ ハヒフヘホ
マみムめモ まミむメも
や ユ よ ヤ ゆ ヨ
ラりルれロ らリるレろ
わ ヲ ん ワ を ン
ァィゥェォ ぁぃぅぇぉ
っゃゅょ  ッャュョ 
ガギグゲゴ がぎぐげご
ざじずぜぞ ザジズゼゾ
ダヂヅデド だぢづでど
ばびぶべぼ バビブベボ
パピプペポ ぱぴぷぺぽ
続きを読む

Perlで文字列操作を学ぶための自作ドリル(英大文字/英小文字)

研修生に教えるための問題と解答例を作ってみた。

問題

英小文字→英大文字(キー入力→画面出力)

実行結果

$ perl uppercase.pl
abcde(改行)
ABCDE
This is perl program.(改行)
THIS IS PERL PROGRAM.
12345xyz ZYX67890(改行)
12345XYZ ZYX67890
(Ctrl+Dで終了)$
英大文字→英小文字(キー入力→画面出力)

実行結果

$ perl lowercase.pl
ABCDE(改行)
abcde
This is Perl Program.(改行)
this is perl program.
12345xyz ZYX67890(改行)
12345xyz zyx67890
(Ctrl+Dで終了)$
単語頭文字のみ大文字(キー入力→画面出力)

実行結果

$ perl upperfirstcase.pl
abcde(改行)
Abcde
ABCDE(改行)
Abcde
This is perl program.(改行)
This Is Perl Program.
THIS IS PERL PROGRAM.(改行)
This Is Perl Program.
12345xyz ZYX67890(改行)
12345xyz Zyx67890
(Ctrl+Dで終了)$
単語頭文字のみ大文字(ファイル入出力)

実行結果

$ perl uppercasefirst_textconv.pl source.txt result.txt

変換元ファイル(source.txt)

abcde fghij klmno pqrst uvwxy
zABCD EFGHI JKLMN OPQRS TUVWX
YZ123 45678 90+-* /^\%=

変換結果ファイル(result.txt)

Abcde Fghij Klmno Pqrst Uvwxy
Zabcd Efghi Jklmn Opqrs Tuvwx
Yz123 45678 90+-* /^\%=
続きを読む

Selenium IDEでWebアプリのテストを自動化

Selenium IDE
ブラウザで行った動作をマクロで記録し、その動作を再現してくれるFirefoxアドオン。

記録した動作はテーブルで表示され、ソースとして読むこともできる。

ソース形式はDHTMLで、こんな感じ。

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">;
<html xmlns="http://www.w3.org/1999/xhtml"; xml:lang="en" lang="en">
<head profile="http://selenium-ide.openqa.org/profiles/test-case">;
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<link rel="selenium.base" href="" />
<title>New Test</title>
</head>
<body>
<table cellpadding="1" cellspacing="1" border="1">
<thead>
<tr><td rowspan="1" colspan="3">New Test</td></tr>
</thead><tbody>
<tr>
     <td>assertTitle</td>
     <td>テストページのタイトル</td>
     <td></td>
</tr>
<tr>
     <td>clickAndWait</td>
     <td>link=テストデータ登録</td>
     <td></td>
</tr>
<tr>
     <td>assertTitle</td>
     <td>テストデータ登録画面</td>
     <td></td>
</tr>
<tr>
     <td>clickAndWait</td>
     <td>//div[@id='test_list']/fieldset/table/tbody/tr[5]/td[1]</td>
     <td></td>
</tr>
<tr>
     <td>assertTitle</td>
     <td>テストデータ登録画面</td>
     <td></td>
</tr>
<tr>
     <td>type</td>
     <td>itemName</td>
     <td>テストアイテム01</td>
</tr>
<tr>
     <td>select</td>
     <td>testOptionId</td>
     <td>label=テストオプション03</td>
</tr>
<tr>
     <td>clickAndWait</td>
     <td>//input[@value='次へ']</td>
     <td></td>
</tr>

:
:

</tbody></table>
</body>
</html>

大量のテストデータを色々なパターンで入力したい時は、ソースの内容をコピーして、フォーム入力内容などを変えるだけで、単調なテストを自動化できる。