‘Perl’ タグのついている投稿

PerlのXML::LibXMLモジュールでShift_JISのXMLのパース

2017/07/27

 PerlのXMLパーサーモジュール、XML::LibXMLで文字コードShift_JISのXMLをパースしようとしてしばらくハマったので将来の自分用にメモを残しておきます。

$doc = $parser->parse_file(〜)でエラー

 XML::LibXMLは$doc = $parser->parse_file(〜)の書式で外部XMLファイルのパスを指定して直接読み込めるのですが、どうもうまくいきません。
用意した読み込み元のXMLは次のような感じ。

 これを以下のコードでパースしようとして

 以下のようなエラーが返ります。

エラー

読み込み元のXMLの文字コード(と宣言文)をUTF-8に変えてやれば普通に読み込めるので、Shift_JIS由来の問題に間違いないようです。どうもXML::LibXMLの$doc = $parser->parse_file(〜)がShift_JISに対応していないのが原因のよう。

$doc = $parser->parse_string(〜)でもエラーになる

 困ったなということでネットでいろいろ情報を集めたのですが、use utf8;を宣言していない例とかしか引っかからなくて困りました。Perlの内部コードをShit_JISにしてやりゃそりゃ読めるでしょうが、Unicodeにしかない文字とか扱う可能性があるのでそれじゃダメなのよ。
 ということで作戦2として、一旦encodeモジュールを使って内部文字列として読み込んでやり、それを$doc = $parser->parse_string(〜)でパースしてみます。コードは以下。

 しかしこれでもエラー。

やはりエラー
 んー・・・

$doc = $parser->読み込んだ文字列内の文字コード宣言の部分を置換して読み込ませて解決

 どうしたものかなとしばらくいろいろ($dom = XML::LibXML->load_xml();方面とか)試していたのですがうまくいかず。
 もう一度エラー内容とコードを眺めていたら、もしかして読み込みXMLソース内の「encoding="Shift_JIS"」の宣言がイタズラしてるのでは?と思い、一行追加。

 これでうまくパースできました。

 いやあ文字コードって本当に面倒ですね。

(2017.7.27)

EpubCheckでID名がエラーになる問題

2016/08/03

 先日、弊社で作ったEPUBファイルが電子取次さんのチェックに引っかかって修正で戻ってきたという件がありました。EpubCheck※1のエラーとのことなのですが、弊社でのチェッカーのログはエラーになっていない。どうもEpubCheck3.0.1ではエラーとなっていたものがEpubCheck4.0.1でエラーにならなくなり、チェックに引っかからなかったということのようです。ちょっと困った事態なので突っ込んで調べてみました。

XHTMLのID名のエラー

 エラー内容は「value of attribute "id" is invalid; must be an XML name without colons」とのことだったので、まずは該当箇所を見てみます。ID名が「id="toc-001*"」のような形となっており、なるほどこれはエラーになるわけだと一旦は思いました。XMLではID名に「*」の記号を使うことを許容していないからです※2。ということでまずはEpubCheckの各バージョンでこの状態のEPUBでエラーになるかを見てみます。

 EpubCheck3.0.1だと
EpubCheck3.0.1でのチェック結果

 なるほどエラーとなるようです。

 EpubCheck4.0.1だと
EpubCheck4.0.1でのチェック結果

 エラーになりません。なるほど。

 では、ちょっとID名を変えて見てみます。「id="toc-あ001"」と、ひらがなの「あ」を入れてみました。この状態でEpubCheckをかけますと

 EpubCheck3.0.1で
EpubCheck3.0.1でのチェック結果

 おや、エラーになりませんね。

 同じくEpubCheck4.0.1だと
EpubCheck4.0.1でのチェック結果

 こちらもエラーにならないようです。

HTML5ではID名に何を使ってもよい

 困った話だなと思ったのですが、さらに調べるとどうもHTML5では途中にスペースが入らない限りID名に何を使ってもよいとの話もあるようで※3、これに従うと挙動としては実はEpubCheck3.0.1でエラーになるのが間違いだったということになるのでしょうか。
 ただ、EPUB3を内部的にXMLなどに変換して表示しているビューアも存在しますので、XMLのID名使用可能文字の制限に従っておくのが無難なのは間違いないと思います。ということでどうやらこの件ではEpubCheckを当てにできませんので、独自にPerlでチェッカーを作ってみました。

 こんな感じでしょうか。一応これでチェックは可能となりました。ターミナルで引数にEPUBファイルを指定してやることでログファイルを出力します。環境によってはArchive::Extractモジュールのインストールは必要かもしれません。

 EpubCheckはIDPFが配布している公式なEPUBの構造チェッカーですので、まずはこれを通るデータであることが市場流通させられるEPUBの最低条件であることは言うまでもありませんが、各パラメータチェックの細かな部分を見ていくと、必ずしもEpubCheckだけで十分というわけでもないようです。現場サイドでの対応も必要といったところでしょうか。

*1 IDPFの提供している公式なEPUBデータチェック用バリデータ。これでエラーとならないことが市場に流通させられるEPUBの最低条件。

*2 半角の英数字および「.」「:」「_」「-」のみ使用できる

*3 参考:https://www.marguerite.jp/Nihongo/WWW/RefHTML/Attrs/id.html

追記:XML関係の有識者の方にコメントいただきまして、どうやら規格としてはHTML5およびそれを内包しているEPUB3ではID名にはどんな文字を使ってもよい、ということで確定のようです。ただ、実際には古いXML規格で回っているシステムは多数あるかと思いますので、ID名にひらがなや漢字、旧規格で認可されていた以外の記号類を混ぜるようなことはしない方が無難だろうとは思います。規格と実装はまた別です。

(2016.8.3)

濁点のトラブルに遭遇

2015/02/09

 最近あったちょっとしたトラブルについてちょっとメモ代わりに。epubはおおざっぱに言えばxhtmlをzipで固めたようなものなので、各xhtmlファイルには当然ヘッダ部分があり、タイトルがあるわけなのですが、このタイトル部分に含まれている文字の濁点の部分が「非濁点親文字」 +「゛」の合字になっており、一部のビューアで合字をきちんと表示できないため、問題となりました。以前からFinder内で入力された文字がOS XのUnicode正規化処理によって変換される問題があるという話は知っていたのですが、実際にトラブルに遭遇したのは初めてでした。Unicode正規化処理に関しましてはものかの先生が詳しく解説してますのでこちらの記事を。

OS Xの処理によって濁点が分解される

 ざっくり何が起きるのかというと、Finderでファイル名等を入力すると、入力時に例えば「ダ」が「タ」+「゛」に分解されて収納されるということです。商用アプリ等では通常これを見越して再変換処理を行っていると思いますので、そういったアプリだけを利用して仕事を完結させているとこの現象に気づかないケースも多いかと思いますが、自家製スクリプト等でファイル名、フォルダ名などを取得して処理するようなケースではきちんとした対策が必要になってきます。今回はそれをしていなかったために合字が混入してしまいました。

 やらなきゃならない処理としては簡単で、変化している可能性のある文字をリスト化して順番に置換をかければいいわけです。ということでものかの先生のサイトで公開されているひらくんさんのperlスクリプトを参考に置換処理を実行。

 これを混入の可能性のある各文字列に対して実行するだけです。

チェッカースクリプトにも処理を追記

 ついでに、最終出力EPUBに濁点(U+3099)、半濁点(U+309A)が混入していないかどうかをチェックする処理を以前に作ったスクリプトに追加しました。

ログ出力用変数に

を追記、

最終出力ログの分岐処理部分に

を追記、

ログ出力部に

を追記、

各キャラクタのチェック用サブルーチン内に

を追記。

出力ログ これでEPUBファイル内に濁点(U+3099)、半濁点(U+309A)が混入していた場合にはチェッカーログに出力されるようになりました。

 以下改訂後の全文です。

 いやまあ今まで経験したことないことがいろいろ起きてきますねえ。刺激はたっぷりあります。今回はものかの先生のお話を聞いておいて本当に助かりました。このお礼はいずれ豆大福などで。

改訂後のMac用ドロップレットです。
>>EPUB3トータルデータチェッカー1.3.0(Mac用アプリ) ダウンロードはこちら

(2015.2.10)

プロフィール
Jun Tajima

こちらにて、電子書籍&Web制作を担当しています。
このブログは、EPUB3をはじめとした電子書籍制作担当オペレータからの、「電子書籍の制作時にたとえばこんな問題が出てきていますよ」的な「現地レポート」です。少しでも早い段階で快適な電子書籍閲覧・制作環境が整うことを願って、現場からの声を発信していこうと目論んでおります。

当ブログ内の記事・資料は、私の所属しております組織の許諾を得て掲載していますが、内容は私個人の見解に基づくものであり、所属する組織の見解を代表するものではありません。また、本ブログの情報・ツールを利用したことにより、直接的あるいは間接的に損害や債務が発生した場合でも、私および私の所属する組織は一切の責任を負いかねます。

最近のコメント