] 2. IO 連続的なテキストイベントを SAX フィルターで結合 self. complete text node( ) def method(self, *a, def wrap_complete(method name) : self. accumulator. append(text) def ignorableWhitespace(self, (s) : self. accumulator. append(text) def characters(self, text) : self. accumulator = self. downstream. characters(' . join(self. accumulator)) if self. accumulator: def complete text node(self) : _wrap complete(n) processinglnstruction comment ・ ・・ split( ) : f0 て n in 凵 startElement startE1ementNS endEIement endEIementNS setattr(text normalize filter, method name, method) name = method name # 2.4 only: meth0d. getattr(self. downstream, method name)(*a, ー 489 name import sys maln from xml import sax from xml. sax. saxutils import XMLGenerator = sax. make parser( ) parser # XML ジェネレータとは元から定義されている特別な SAX ハンドラで、 # SAX イベントを XML 文書に書き戻すだけのもの downstream handler = XMLGenerator( ) # upstream にこのノ←サ、 downstream にチェーン中で次にあるハンドラ filter handler = text normalize filter(parser, downstream handler) # SAX のフィルタベースがそのように設計してあるため、フィルタが # ノ←サのインタフェースの多くをまかなう。 parse メソッドもそのひとつ filter handler. parse(sys ・ argv[l]) 考察 になる。よく使っているパーサがこうしたテキストノードを結合してくれるとしても、べつのパーサしかな SAX ハンドラの方でこれを考慮に入れていないと、まったく不明瞭、かっ再現の難しいバグにでくわすこと べントのラップを終えてしまう。次のバッフアにあるテキストは、新しいイベントに送り込まれるのである。 ている。テキストノードがバッファ境界にまたがる場合、多くのパーサがそのとき処理しているテキストイ である。低レベルバーサのほとんどは、一度に一定数のキャラクタを読込んで解釈するのにバッフアを使っ パーサがテキストノードをちょっとすっレポートする典型的な理由は、 XML 入力ソースのバッファリング 重イベント化は、実生活では起きそうにないが、あり得ないことではない。 ントとして報告される可能性がある。 こまで極端な「フラグメンテーション」っまりテキスト文字列の多 があるとして、このテキストが技術的には最大 3 つ、つまり「 a 」「 b 」「 c 」という 1 っすつのキャラクタイベ の複数回コールという意味 ) としてレポートすることがある。言い換えると、「 abc 」という内容の XML 文書 SAX パーサは連続したテキストを複数のキャラクタイベント ( 実際には下流ハンドラの ( haracters メソッド
イントロダクション 3 これはアプリケーション固有の ファイルフォーマットをパースするもので、 shlex モジュールを基にしている。 shlex は、基本的な言語用に 設定ファイルがある。パーサの例としては、他に netrc モジュールがあるが、 よびファイル的オプジェクトの write メソッドをもってすれば、たやすい。これは、出力ファイルをパラメー アプリケーション固有のデータ構造からテキストデータを取り出すことは、 python の print 文や、 file お メモリに入っているテキストを扱うこともある。 スト以外に対しても適用できる、変換手法を見て回る。外部ファイルに入ったテキストを扱うこともあれば、 見た方がおもしろい。我々がテキスト云々と言う場合、ます頭に浮かぶのはこの処理だ。この章では、テキ ある形式のテキストを別のフォーマットに変換するという行為は、テキストの加工 (textprocessing) として のアドオンパッケージに依存している。こちらについては 16 章のイントロダクションで概説する。 れを使ったレシピは 2 章や 13 章にある。 thon では、もう少し本格的な構文解析機も使える。これらは大型 からコマンド入力を許す場合に有効である。 th 。 n の標準ライプラリには、この手の専用パーサが豊富で、 まあそこそこのトークナイザを提供するもので、人間に読める設定ファイルを作ったり、対話型プロンプト テキストのソース 体に見受けられる。 きないだろう。処理すべきテキストの入力がないからだ。まあ p ⅱ nt や w ⅱ te の用例は、当然ながらこの本全 といった文により、適切なファイルが出力される。とはいえ、これを一般的なテキスト処理と言うことはで thefile. write(sometext) print >>thefile, sometext タに取るアプリケーションオプジェクトのメソッドや関数によって行われることが多い。関数では : ソッドにより ) ファイルと見なせるのだが、到着するデータについては、ある程度の塊として得られることも、 トワークから来るテキストはソケットで得られることが多い。ソケットは (socket オプジェクトの makefile メ テキストのデータを生成する源としておもしろいのがもう 1 つあって、つまり、ネットワークである。ネッ パフォーマンス上有利なことがある。ファイルにまつわるレシピは 2 章にある。 由による。大きめのデータで作業する場合でも、バッフアを注意深く管理してやれば読み書きの回数が減り、 がもたらされることがあるが、これは単純に、プログラムを走らせるだけのスペースが確保できるという理 はデータの一部しか必要としない場合、データを小さく分けて作業することで、相当のパフォーマンス改善 り 80MB のファイルなんて、そう簡単に読んでられるかいな、ということだ。アプリケーションが、一度に 上のデータを扱う場合、メモリにすべてロードすることはしない場合が多い。これはサイズのせいで、つま データ量と I/O パフォーマンスとの兼ね合いによっては、かなりのオーバーヘッドが出るからだ。ディスク ファイルべースの変換については、特別な扱いをしてもよいだろう。メモリに実際に保持せねばならない クトのメソッド群、すなわちビルトイン文字列操作の良いところが、非常に簡単に活かせる。 についても、特に気にしなくてよい。テキストを単純文字列としてメモリ上に持ってやると、 string オプジェ テキストを検索する操作は、複数行に対して簡単かつ高速に行われるので、バッファ境界の類をまたぐ問題 テキストが大きすぎない限り、メモリに文字列として格納されたテキストを扱うことは、だいたい易しい。
2 1 章テキスト ( 「 Un ⅸ」界でよくある ) か、形式や内容を示す既知の拡張子を持つ ( Windows によくある ) からこそ、我々はこ れを見ているのである。しかしここに問題が生する。いま言ったことが意味を成すには、「形式」という単語 を使う必要があるではないか。シンプルなテキスト、を想定したはずではなかったのか。 現実を見よう。「純粋な」テキストなど存在しない。あるとしても、それは我々に縁のないものだ ( 数理言 語学アプリケーションという例外はあり得るが。この分野ではピュアなテキストがそれ自体を目的として研 究されることがあるす ) 。我々がアプリケーションで扱いたいのは、テキストに含まれた情報だ。我々のテキ ストとは、設定情報であり、処理の制御や規定を行うコマンド群であり、さらには人に読ませるドキュメン トだ。表になったデータというのもあるかもしれない。設定情報や一連のコマンドが書かれてあるテキスト は、中の情報に頼らず形式チェック可能な、それなりに厳密な文法に従うものと想定できる。チェックでェ ラーが出たときにユーザに知らせてやるだけで、想定外の事態への対応としては十分だ。 人に読ませる想定のテキストは、割とシンプルなのが普通だが、細部には非常な幅がある。これらは通常、 自然言語で書かれるので、その文法チェックは困難 ( 最良の場合でも ) である。異なるテキストには異なるキャ ラクタセット、すなわち工ンコーディングが使われうる。作成に使われたキャラクタセットやエンコーディ ングの情報が別に与えられないと、この判別は困難であり、まるで不可能な場合もある。とはいえ、自然言 語を正しく表現したドキュメントのサポートは必須である。自然言語で書かれたテキストにも構造はあるが、 これはテキストそのものからは、それほど明らかではないので、書かれた言語の側を、いくらか理解してお く必要があることが多い。つまり、文字は単語を作り、単語は節を、節は段落を作り、さらに上位の構造も あり得る、といったようなことだ。段落 1 つをとっても、体裁が分からなければ、その特定が非常に難しい ことがある。たとえば 1 行をもって段落となすのか、それとも複数行の段落も許されるのだろうか。もし後 者ならば、行のつらなりが段落であることを、どのようにして知ればよいのか、などといったことだ 。っ した段落は、空白行や字下げの他、なんらかの特殊記号で示されている場合もある。 表のデータには、自然言語テキストに似た問題がかなりある上、第 2 の次元がある。テキストはもはや線 形ではないのだーーーーキャラクタの列というよりキャラクタの行列 ( マトリックス ) というべき物になる。個々 構文解析はさまざまな方法で行われる。フォーマットの多くは、専用のパーサをあてがえば扱え、制限の データをイチから生成する 入力を変換し、元と似ているが何らかの意味で異なったものとする データをパース ( 構文解析 ) してアプリケーションの内部形式とする え、依然として基本操作というべきものが 3 っ存在する。 どのデータ形式でもそうだが、テキストに対しても、場合に応じて異なることをする必要がある。 基本のテキスト操作 のテキストプロックをこの中で特定し、再構成せねばならない。 とはい す訳注 : 翻訳アプリケーションというのもあるね。 mail ヘッダ ( python 標準ライプラリの幵 ( 822 モジュールを参照 ) や、朝 nfigParser モジュールで扱えるような きついフォーマットでは、これがなかなか有効である。このアプローチの例として、 RFC2822 スタイルの e -
1 外部入力を扱うからには、普通ベストなアプローチだ。そのファイルが特定の形式で既知の名前を持っ まあよし。アプリケーションは、周囲の状況から、受け取るのがテキストであると想定できるものとする。 文字列を相互変換」、「レシピ 1.22 標準出力に Unicode 文字を出力」で例示している。 おける Unicode の原則は、「レシピ 1.20Unicode で多言語テキストを扱う」、「レシピ 1.21Unicode と通常の たものを使う。 U ⅲ code 文字列には、バイトの並びとしての機能を持たせられないことに注意せよ。 python に がどのようなバイトの並びに表現されるかという知識 ( 工ンコードとキャラクタセット、とも言う ) を内包し 相互変換には、 codec( コーデック :coder-decoder) オプジェクト群、すなわち、各国の標準に従うキャラクタ 場合は多い。 Unicode 文字列は Unicode キャラクタの不変な並びである。 Unicode 文字列とプレーン文字列の 処理では、これをキャラクタの並びとして扱う手法がほとんどだが、同じ手法をバイトの並びに適用できる th 。 n において、文字列とはバイトや文字 ( キャラクタ ) の変更不能 ( 不変 ) な並びである。文字列の生成や の手の発見的方法を示している。 ス ( 発見的方法 ) を創ることはできる。「レシピ 1.11 文字列がテキストかバイナリかを調べる」では、まさに データをテキストとして扱っても安全か ( 正しいか、である必要はない ) 教えてくれる、ヒューリスティック ト列がテキストであるかどうか、教えてくれるようなライプラリ関数は存在しない。とはいうものの、ある ところがどっこい、すべてのデータはバイトの並びとしてアプリケーションに入力されるのだ。あるバイ バイナリデータと区別されるものだ。バイナリデータとはバイトの並びだ。 簡単な質問だ、と思うでしよ。実際見ればわかること。テキストとは文字の並びであり、この事実により テキストとは何か のは至難であるということだ。 ンと少しは異なっているので、いくらファイル形式が似ていても、びったり再利用できるコードを見つける たいテキストを持っているものだ。大事なのは、どんなアプリケーションも、ほかの全てのアプリケーショ 便利という程度の理由かもしれないが、とにかくそうなっている。どんな人でも形式を整えたり変換を掛け どのスクリプト言語でも、テキスト処理がアプリケーション空間に占める割合は大きい。テキスト処理は Credit: Fred L. Drake, Jr. 訳 : 鴨澤眞夫 1 .0 イントロダクション テキスト
Unicode の数値コードへの変換 . 文字列のように振る舞うかの テスト . オプジェクト指向 .. Template Meth0d ~ Strategy ~ State ~ Singleton ~ NuII Object ~ M 0n0 state Adapter ~ デザインパターン .. 文字列のように振る舞うか ファイルから読む .. テキスト処理の基本操作 .. 操作… 整形 .. 処理 .. 検索・置換 .. 空白文字の刈り込み .. Word ファイル . 614 ー索引 フィールド名 .. メソッド・関数の発行 . ンヨン . ディレクトリ 定数… レーティング機能 .. 相対パス .. ディレクトリツリー ファイルの探索… データベース . marshal モジュール . pickle/cPickIe モジュ 永続性… プログラミング… デーモンスレッド . デーモンプロセス .. HTML を変換する .. テキスト . … 97 … 89 … 90 … 296 … 298 … 301 … 293 ... 361 … 392 .. 1-56 … 55 .. 102 .. 104 … 67 .. 1-56 … 320 … 179 … 224 … 240 … 293 , 311 トレースパック . 例外のトラソプ 添付 .. テンプレート . 特殊メソッド . ドラッグ & ドロップ トレースパック . 夏時間 .. な行 ール . OpenOffice.org からのテキスト抽出 .. のテスト . … 232 , 274 … 228 , 235 … 344 ... 366 ... 341 … 255 ... 337-358 ... 379 , 389 … 343 .. 10 … 337-358 ... 62-65 … 232 … 274 … 272 … 281 … 279 … 89 … 272 .. 10 二分挿入法 (binary insertion sort) . パフォーマンス バックスラッシュ ( \ ) . バックアップ .. パスワード . バイナリモードとテキストモード . ランダムに読む .. バイナリファイルを読む .. シーケンシャルに読む . バイナリファイル テキストデータとの区別 . Windows の標準出力 .. バイナリデータ ランダムに読む .. シーケンシャルに読む . CRC-64 の計算 .. バイト列 .. テキストの ~ MSHTML での ~ は行 モニタリング .. ダイナミック IP アドレス .. コンピュータの検知 .. ネットワークプログラミング .. プロクシ .. SSL クライアント . 二分探索 .. 例外のトラップ ... デバッグモード . スレッド . ガべージコレク、 pr 叩 erty 関数 .. デバッグ .. デッドロック . invert dict_fast と invert dict . isorted 関数と sorted 関数 .. O ( ) 記法 ... sort メソッドと select メソッドの比較…… 216 アルゴリズムと ~ サーチパスの変更 .. … 347 ... 338 … 342 … 564 … 503 , 507 .. 552 ... 596 … 213 .. 195 .. 132 ... 347 ... 433 … 250 ... 400 , 590 , 593 … 43 , 58 … 491 … 519 … 528 … 514 … 493-535 … 5 , 57 ... 107 … 396 ... 58 … 74 … 58 … 66 … 82 … 74 … 66 .. 109 … 94 … 207 … 201 … 212 .. 177
1.11 文字列がテキストかバイナリ調べる一 25 解法 perl のものと同様のヒューリスティクスによる評価基準が使える。すなわち文字列にヌル文字が含まれる 場合やキャラクタの 30 % 以上にハイビットがセットされている ( つまりコードが 126 以上である ) 場合や、お かしな制御コードが含まれる場合に、これをバイナリとみなすのだ。コーディングは自分でやる必要がある が、これは自分の用途向けに調整する余地があるということでもある : 行 om future import string import division # / で切り捨てが起きないようにする '. join(map(chr, range(32, 127 ) ) ) text characters = = string. maketrans(" null trans def istext(), text characters=text characters, th て eshold = 0.3 の : # null 文字が入っていれはテキストではない : if " \ 0 " in s: return False # 「空」文字列はテキストである ( この選択は任意だが、まあ合理的でしよう ) : if not s : return True # s から非テキスト文字のみを抜き出しサプストリンクを作る = s. translate( null trans, text characters) t # 非テキスト文字が 30 % 未満であれば 5 は「テキスト」である : return len(t)/len(s) く = threshold 考察 関数 istext では、 threshold 値 ( デフォルトは 0.30 で 30 % ) や、「テキスト」とみなされる文字列の集合 text characters ( デフォルトは通常の ASCII キャラクタ + テキストによく含まれている「普通の」コントロー ルキャラクタ 4 つ ) を指定することにより、内部の発見的アルゴリズムを少しだけカスタマイズできる。 たとえば ISO -8859-1 でエンコードされたイタリア語の文字列を扱うなら、イタリア語で使われるアクセン ト付きの文字発 i " を引数 text characters に追加することができる。 バイナリかどうかチェックしたいのはただの文字列ではなくファイルである、ということは多い。この場 合にも perl と同じ発見的手法が使える。ファイルの最初のプロックのみを istext 関数でチェックすればよい のだ・ def istextfile(filename, blocksize=512, **kwds) : return istext(open(filename). read(blocksize), **kwds) 関数 istext のボディにある式 len ( t ) / len ( s ) は整数同士の徐算であり、デフォルトでは結果が 0 に切り捨て られることに注意されたい。将来 ( たぶん何年か先の塚 thon3.0 あたり ) の thon では / 演算子の意味を変更 し、徐算は切り捨てを行わないようになる一一切り捨てが必要な場合には切り捨て付き徐算演算子 / / を使う ことになる。 とはいえ、今はまた thon の徐算セマンティクスは変わっていない。以前からのセマンティクスをデフォ ルトとすることで後方互換性を保証しているのだ。 Python2. x の全バージョンで、既存のプログラムやモ
OpenOffice. o 「 g 文書からテキストを抽出ー 103 if name 2.26 maln import sys if len(sys ・ argv)>l: for docname in sys ・ argv[l: ] : print 'Text 0f ・ , docname, print convert 00(docname) print 'XML 0f' , docname, 対応するテキストファイルに抽出したい。 Windows 上の、あるディレクトリツリー内の MicrosoftWord 文書それぞれのテキスト内容を、 問題 credit: Simon Brunning, pavel Kosina 訳 : 吉宗貞紀 227 Microsoft Word 文書からテキストを抽出 /www.叩enoffice.0r臨) 、「レシピ 12.3 テキストの抽出」。 ライプラリリファレンスの zipfile とて e 両モジュールに関する解説、 ()pen()ffice.org のウエプサイト (http:/ 参照 については「レシピ 12.3 テキストの抽出」で述べる。 に置換されるというのがポイントである。 XML 文書から全てのテキストを抽出するための、より進んだ手法 プランク文字で結合する ) 。この「切断 - 再結合」の過程で、全てのホワイトスペースが 1 個のプランク文字 続したホワイトスペースにより、文字列を切断する ) 、再結合する ( " . j0in による。これは要素間を 1 個の するために一旦 split した後 ( つまり文字列オプジェクトの split メソッドを呼び出す。 split は 1 つ以上の連 この正規表現により全ての XML タグをそれぞれ 1 個のスペースに置換し、さらにホワイトスペースを標準化 いようが閉じていようが ) にマッチする。 convert 開関数の中の、 "ifwant-text" でガードされた文において、 具体的に説明すると、正規表現オプジェクト rx_stripxml はくで始まり〉で終わる全ての XML タグ ( 開いて 分だろう。 必要としているのがテキストの大ざっぱな内容でしかないならば、この速くて手軽でラフなアプローチで十 もちろん XML の構文解析を行うことで、はるかに豊富な情報をより体系的な手法で獲得することもできるが、 スペース ( 複数のプランクやタブ、改行などを含む ) で split してから単一のプランクによって再び結合する。 作では、シンプルな正規表現によって XML タグを切り捨て、表示を小さく行うために、この結果をホワイト いる。だから、このレシピの主な仕事はそのファイルを解凍して取り出すだけなのである。デフォルトの動 OpenOffice.org 文書は zip ファイルであり、様々なコンテンツに加え、常に content. xml ファイルを含んで 考察 print ' 朝 11 with paths t0 開 .0 doc files t0 see Text and XML forms. else: print convert 00(docname, want text=False)
298 ー 7 章永続性、データベース 7.2 pickIe/cPickIe モジュールを利用してシリアライズする 解法 度でシリアライズ、デシリアライズしたい。 p hon の基本的なオブジェクトに加え、クラスやインスタンスも含んだデータ構造を十分な速 問題 Credit: Luther BIissett 訳 : 當山仁健 ピ 7.11 」を、 SQLite に保存するには「レシピ 7.12 」を参照。 す BLOB として MySQL に保存する方法については、「レシピ 7.10 」を参照。 PostgreSQL に保存したい場合は「レシ loads 関数が自動的に判断し、適切に復元してくれる。 トモードを利用したか、バイナリモードを利用したか明示的に指定する必要はない。どちらを利用したか で保存した時の順番のまま復元される。 ( Pi ( kle. loads を使うときには、元のデータを dumps するときにテキス ナルのデータでの順序が保たれたまま復元される保証はないが、シーケンスでは順序自体にも意味があるの 上の方法でデータを再構築することができる。ディクショナリのキーの順序は任意のものなので、オリジ = cPickle. loads(bytes) redatal = cPick1e. loads(text) redata2 ればアーキテクチャや thon のバージョン間の違いを気にせすにデータを好きなときに復元することができる。 また、テキストであれば、改行文字も含めてテキストの構造を保っということを意味している。それさえ守 でいう「変更を加えない」というのは、バイト列の場合、バイナリの順序を保っということを意味している。 うことができる。ネットワーク越しに送ったり、 BLOB としてデータベースに保存することもできるす。 高速に行われ、サイズも小さくなる。変換したテキストやバイト列は、変更を加えない限り好きなように扱 デフォルトではテキスト文字列にシリアライズされる。バイト列への変換はテキスト文字列への変換より bytes = cPickle. dumps(data, 2 ) もしくはノヾイト列に変換することもできる。 text = cPick1e. dumps(data) import cPick1e 以下の操作でデータをテキスト文字列にシリアライズできる。 data = { 12 : 'twelve' lfeep':list('ciao'), 1.23 : 4 + 5j , (1,2,3):u'wer'} たとえば、次のようなデータ構造を扱うときについて考える : て cPickIe と同じ機能を持っているが、低速なため cPick1e が利用できない場合以外に使う価値はない。 の互換性を保ちたい場合には ( Pi 〔 kle モジュールを使うのが最適である。 pickle は thon のみで書かれてい データが thon の基本的なオプジェクトだけで構成されている確証がない場合や、 thon のバージョン間
58 ー 2 章ファイル レクトリにあるものとみなされる ( import 処理に適用される thon のモジュールサーチパスとは全く異なる 考え方である ) 。 モード引数としては、ファイルをテキストモードで読み込む場合てを使用する。これはデフォルト値であり 普通は省略されるので、 open を 1 つの引数で呼び出すこともできる。他の一般的なモードとして、バイナリ モードでの読み込みに rb 、テキストモードでのファイルの作成と書き込みに w 、バイナリモードでのファイ ル作成と書き込みに wb を用いる。 r のバリエーションとして重宝するものに rU がある。これはファイルを「ユ ニバーサル改行」のテキストモードで読み込むよう thon に指示する。て U モードではテキストファイルを、 そのファイルが用いている改行コードに合わせて読み込むことができる。それが Un ⅸであれ、 Windows であ れ、 ( 古い ) Macintosh であったとしても ( 現在の MacOSX は誰がどうみても Un ⅸであるが、ちょっと前の Mac OS 9 までは全く異なっていた ) 。 非 Unix 的なプラットフォームではテキストモードとバイナリモードを識別することが重要だが、これは使 われている行末コードのためだ。バイナリモードでファイルを開いた場合、 thon は行末コードに注意を払 わなくてもよいと判断する。ファイルやメモリ上の文字列をただバイト単位で移動し、何の変換もしない。し かし非 Un ⅸ的なシステムでファイルをテキストモードで開いた場合には、 thon は文字列で使われている行 末コード \n を、現在のプラットフォームがファイル内で使っている何かと相互に変換する。ファイルを開く 際には、テキストなのかバイナリなのか、モードを適切に示しておけば、コード上では \ n が常に行末コード であると信頼できる。 このあとすぐに触れるが、ファイルオプジェクトを生成すると、そのオプジェクトのメソッドを呼び出す ことにより全てのファイル入出力作業を行えるようになる。ファイルの操作が終わったら、最後にこのオプ ジェクトの close メソッドを呼び、ファイルとの接続を閉じるべきである : input. close( ) 短いスクリプトではしばしばこのステップが省略される。 thon は、ガべージコレクションの過程でファ イルオプジェクトを再利用する際に、自動的にファイルをクローズするからであるにれは現在主流の thon では、ファイルはほとんど即座にクローズされることを意味する。一方、他の重要な thon 実装である J hon や lron th 。 n などは、もっと緩やかなガべージコレクション方針を採用している ) 。いずれにせよファイルを できるだけ早くクローズすることは良いプログラミング習慣であり、大きなプログラムー一言い換えると、使 用しない余計なファイルがオープンされたままごろごろしていることのリスクがより高いであろうプログラ ムでは、特に推奨される考え方である。ちなみに確実なファイルのクローズには try / finally を使うとよい。 これならキャッチされない例外により関数が終了する場合でもクローズが保証される。 ファイルに書き込むには write メソッドを用いる : output. write(s) s は文字列である。 s は output がテキストモード書き込みでオープンされたときはキャラクタ列、バイナリ モード書き込みでオープンされたときはバイト列であると考えてほしい。ファイルには書き込みに関するメ ソッドが他にも存在する。たとえば flush はバッフアされた全てのデータを送出するし、 writelines は一度の 呼び出しで複数の文字列を続けて書き込む。とはいえ、圧倒的に広く使われるメソッドが w ⅱ te であることは
] 2.6 XML DOM ノードのサブツリーからスペースのみのテキストノードを削除ー 481 組み合わせではなく ) Python オプジェクトのツリーに読み込むことだ。オプジェクトはノードごとに 1 個で、 その ( いい感じに命名してある ) 名前付き属性を使えば、タグ名、属性 ( thon ディクショナリとして読み込 む ) 、文字データ ( XML 用語で言うところの cdata) 、子要素 ( thon リストとして読み込む ) といったノード特 質 (node's characteristics) にアクセスできる。 EIement クラスの種々のアクセッサメソッドは、当然ながらオプションである。属性に直接アクセスしたい かもしれないからだ。私はアクセッサで複雑性が導入されることはなく、見栄えも良いと思うのだが、これ が好み次第なのは明らかだ。結局ただのレシピですから ! シーズニングの混ぜ方はお好み次第よ ! ! 類似のアイディア ( DOM をバイバスし、なにかもっとパイソニックな形で XML 文書をメモリ内に表現する こと ) は、もっと完全な形の素晴らしいプロジェクトとして、すなわち PyRXP (http://www.reportlab.0r臨 pyrxp. html) 、 ElementTree (http://effbot.org/zone/element-index.htm) 、 XIST (http://www.livinglogic.de/Py- thon/xist/) などの形でも存在している。 参照 , thon 標準ライプラリのビルトイン XML サポート、特に xml. p 訂 sers. expat についてのライプラリリファ レンスおよび fPython クイックリファレンス』の解説。 PyRXP は http://www.reportlab.org/pyrxp.html を、 ElementTree は http://effbot.org/zone/element-index.htm を、 XIST は http://www.livinglogic.de/Python/ 12.6 XML DOM ノードのサブツリーから xist/ 。 解法 きたい。 DOM で表現された XML 文書のサブツリー内から、ホワイトスペースのみのノードをすべて除 問題 Credit: Brian QuinIan, David WiIson 訳 : 鴨澤眞夫 スペースのみのテキストノードを削除 # このテキストノードを削除予定リストに加える if child. nodeType = = dom. N0de. TEXT NODE and not child. data. strip( ) : fo て child in node. childNodes: remove liSt = # 削除するテキストノードのリストを準備 ( 必要な時は再帰する ) " DOM ノードからホワイトスペースのみの下位ノードを全て除去 " ” def remove whilespace nodes(node) : ぶらさがったホワイトスペースのみのテキストノードをすべて削除する関数があると助かる。 ノードを保存するかを決める。困ったことに、結果が望み通りでないことがよくあるので、指定のノードに XML パーサは DOM の構築時、いくつもの複雑な条件を勘案してホワイトスペースオンリーのテキスト