XMLをテキストに変換する:山かっこの間から本文だけを取り出す
テキストコーパスを作っていると必ず出くわす種類のファイルがあります。中身そのものは面白いのに、 2006年ごろに誰かが設計したスキーマの下に埋まっているXMLエクスポートです。論文の抄録、裁判記録、 電子化されたアーカイブ、10年分のブログ記事。欲しい文章はたしかにそこにあります。名前空間プレフィックス 付きのタグに三重に包まれているだけです。
このページはその中身を引き出し、テキスト以外は何も返しません。見出しも表も、マークアップの類も一切
つけません。行き先が埋め込みモデル、検索インデックス、NLPスクリプトなど、記号をノイズとして扱う
パイプラインなら、欲しいのはこの形です。上から .xml ファイルをアップロードしてください。
無料、登録不要、50 MBまで、保存は一切しません。
XMLファイルの中身を見たとき、何が残って何が消えるか
抽出は < と > の間を消すだけの作業ではありません。次の点をきちんと
処理しないと、出力は気づきにくい形で壊れます:
- 実体参照はデコードされます。XMLは裸のアンパサンドを含められないので、現実の文書は
&、<、"、それにカーブした アポストロフィを表す’のような数値参照で埋まっています。そのまま残すと 語数がずれ、検索も当たらなくなります。本来の文字に戻して返します。 - CDATAセクションは展開されます。
<![CDATA[ ... ]]>は、 マークアップを含む中身をXMLに持ち込むための仕組みです。RSSのdescriptionに入ったHTML、SQLの断片、 JavaScriptのブロックなど。囲いは外し、中身は残します。 - 空白だけのテキストノードは捨てます。整形済みのXMLは、タグとタグの間すべてに改行と スペースしか入っていないテキストノードを持っています。残せば出力の6割が空行になります。
- 要素名は完全に消えます。Markdown版と違い、ここではタグ名をラベルとして残しません。 手に入るのは値であって、スキーマではありません。
- コメント、XML宣言、DTD、処理命令も消えます。どれも本文ではありません。
語の境界が消えるバグと、それが効いてくる理由
素朴なタグ除去、とくにフォーラムからコピーしてきた正規表現がまず踏むのがこれです。混在内容、つまり 同じ親の中でテキストと子要素が交互に現れるケースを見てください:
<p>詳しくは<ref>付録</ref>を参照</p>
雑にタグを外すと、そのタグが担っていた語の境界ごと消えます。英単語が混ざる文なら二語がくっついて 一語になり、日本語でも文の切れ目が失われた塊になります。逆にタグのたびに改行を入れる実装だと、 一文が3行に寸断されます。どちらも使い物になりません。前者はトークナイズを壊し、後者は文分割を壊し、 そのまま下流の処理へ静かに伝播していきます。
正しい実装はインライン要素をインラインのまま扱い、本当のブロック境界でだけ改行を入れます。別のツールで XMLファイルからテキストを抽出するなら、まずここを試してください。文の途中にインライン タグが入っている段落を探し、文が壊れずに残っているかを見るだけです。
設定ファイルという落とし穴
ここからは正直な注意書きです。知っていれば5分の混乱を避けられます。XMLはデータを2か所に持ちます。 タグとタグの間と、タグの中の属性です。テキスト抽出は定義上、前者しか取りません。そして、ごく ありふれた種類のXMLには前者がほとんど存在しません。
Androidのマニフェスト、.NETの app.config、Antのビルドファイル、SpringのBean定義、
多くのSVG。これらはほぼすべてを属性に書きます。テキスト抽出にかけると、単語がぱらぱら返ってくるか、
空のファイルが返ってきて、ツールが失敗したように見えます。失敗していません。取るべき要素テキストが
最初からなかっただけです。
その種のファイルには XMLをMarkdownに変換するページ を使ってください。属性を、それが修飾する要素にくっつけたまま残します。このページ上部の形式トグルで 切り替えれば選んだファイルも一緒に運ばれるので、アップロードし直さずワンクリックで済みます。目安は 文章は要素に入り、設定は属性に入る。テキスト抽出は前者のためのものです。
フラットなテキストが明らかに正解になる場面
よく整備された文章の膨大な部分は、いまもXMLで保管されています。各機関がJSON登場以前にXMLで標準化した からです。この変換ツールが本領を発揮するのは、まさにその遺産の側です:
- コーパス構築。学術抄録のダンプ、TEIでエンコードされた文学作品、議事録や判例、 博物館と図書館の目録。どれも中身は濃い文章で、どれも重いスキーマに包まれています。欲しいのは 文章のほうです。
- 埋め込みとベクトル検索。生のXMLをそのまま埋め込むと、できあがるベクトルのかなりの 部分が意味ではなくマークアップを表します。まったく無関係な主題の2文書が、同じスキーマを共有して いるというだけで近くに落ちることさえあります。タグを落とせば、中身についての埋め込みが得られます。
- チャンク分割。固定長のチャンカーは生のXMLを要素の途中で切り、閉じられないタグを 抱えた断片を作ります。フラットなテキストなら文と段落の境界で切れます。チャンカーが本来想定して いたのはそちらです。
- 検索インデックスとテキスト解析。単語頻度、感情スコア、トピックモデル、固有表現 抽出。どれもレコードごとに繰り返される構造タグのぶんだけ数字が歪みます。
- トークンの節約。XMLの冗長さは構造化フォーマットの中でも際立っています。要素名を 必ず2回書くからです。深くネストしたエクスポートからタグを落とすと、情報を運んでいなかったトークンが まとめて消えます。出力の下のカウンタに、その差がそのまま出ます。
タグを落とすべきでない場面
モデルは生のXMLを問題なく読みます。冗長ではありますが曖昧さがなく、学習データにも大量に含まれています。 変換は理由があってする判断であって、守るべき規則ではありません。
- その文書を相手にコードを書くとき。XPathのクエリ、XSLTスタイルシート、SAXやDOMの パーサ、スキーマ。どれも正確な要素名、名前空間プレフィックス、属性と要素の区別が保たれている必要が あります。テキスト抽出はまさにそこを削ります。実ファイルの断片をそのまま貼ってください。
- 階層そのものが答えのとき。ある設定がどの環境の下にあるのか、ある条項がどの節に 属するのか。親子関係が問いなら、平坦化はその答えを壊します。Markdownの仕事です。
- 属性中心の文書。前述のとおりです。
よくある質問
XMLファイルをテキストに変換するには?
上のコンバータに .xml をドロップすれば、タグの間の中身がそのまま文章として返ってきます。山かっこも名前空間プレフィックスも属性もありません。.txt でダウンロードできます。無料、登録不要、1ファイル50 MBまで、保存はしません。
& や < のような実体参照はデコードされますか?
されます。しかも見た目以上に効きます。XMLは裸のアンパサンドを含められないので、現実の文書は &、<、"、それに数値文字参照で埋まっています。素朴なタグ除去の正規表現は、それらを文字列のまま出力に残します。きちんとパースすれば、本来の文字に戻ります。
山かっこの間を正規表現で消すだけではだめですか?
CDATAセクションと属性値には、マークアップに見えてマークアップではない文字が入るからです。正規表現は、HTMLを埋め込んだ <![CDATA[...]]> ブロックの中身を平気で食べてしまいますし、引用符で囲まれた属性テキストの中に現れる < を本物のタグと区別する手立てを持ちません。パースならそこを正しく扱えます。パターンマッチは、間違えたことを黙っています。
属性値も出力に含まれますか?
得られるのは要素テキストで、属性は要素の中身ではなく要素についてのメタデータとして扱われます。たいていはそれで正しく、欲しいのは抄録であってスキーマのバージョンではありません。困るのは、実際の中身を属性に入れる形式です。出力が妙に薄いと感じたら、ソースを開いて、目当ての語が <tag attr="..."> の中にいないか確認してください。
RSSフィードやサイトマップでも使えますか?
どちらもXMLなので変換できます。RSSフィードからはタイトル、説明、日付が読めるテキストとして取り出せるので、ブログのアーカイブからコーパスを作るときの近道になります。サイトマップから出てくるのはURLの一覧で、読み物というより別の処理に流し込む素材です。
関連ツール
間接的に出会うXMLについても一言。.docx と .epub は、開けてみればzipされた
XMLです。展開して内部のマークアップをここに流し込むこともできますが、やめたほうがいいです。スタイル
指定と変更履歴のメタデータで飽和していて、本文が埋もれます。
Wordをテキストに変換か
EPUBをテキストに変換を
使ってください。どの部分が本文かを知っています。XMLではなくHTMLのマークアップなら
HTMLをテキストに変換、
もう一方の主要な構造化データ形式なら
JSONをテキストに変換があります。
File2Txt は、ページを選ぶのが
面倒なときに対応形式すべてを受け付けます。
そのXMLがリポジトリの中にあるとき、たとえばPOMファイル、ビルド定義、テストのフィクスチャなどは、 単体で変換すると文脈がはがれ落ちます。 GitHubをテキストに変換するツール、 GitLabコンバータ、 ローカルディレクトリコンバータなら、 XMLとそれを読むコードを1つの出力にまとめられます。ほとんどの場合そちらのほうが役に立ちます。 一般論は LLM向けに ファイルを準備するガイドにまとめてあります。
Repo2Txt を作って運用しているのは v12hero、 プライバシー重視のネイティブアプリとWebアプリを手がける個人開発者です。