構造が良く分からない巨大な XML を処理するため、F# でタグの構造と出現数を調べました。
XmlReader
.NET Framework の System.Xml.XmlReader を使用します。
XmlReader は DOM を作らないプル型のパーサーです。今回のように巨大な XML のタグだけ見るような用途に適しています。
コード
タグの構造を知るため、DOM の代わりのツリーを作ります。同じタグは 1 つにまとめて、出現回数を数えます。
コンパイルして EXE にした場合と、コンパイルせずに F# Interactive に引数で渡した場合のどちらでも使えるように、最後の引数が XML かどうかだけを見ます。
open System
open System.Collections.Generic
open System.IO
open System.Xml
let args = Environment.GetCommandLineArgs()
let xml = args.[args.Length - 1]
if Path.GetExtension xml <> ".xml" then
printfn "usage: CheckTag xml"
exit 1
type Node(name:string) =
let mutable count = 0
let children = Dictionary<string, Node>()
let getChild name =
if children.ContainsKey name then
children.[name]
else
let node = Node name
children.[name] <- node
node
let isEnd (xr:XmlReader) =
xr.NodeType = XmlNodeType.EndElement && xr.Name = name
member __.Parse (xr:XmlReader) =
count <- count + 1
if xr.IsEmptyElement then () else
while xr.Read() && not <| isEnd xr do
if xr.NodeType = XmlNodeType.Element then
(getChild xr.Name).Parse xr
member __.Show() =
for kv in children do kv.Value.Show("")
member __.Show(indent) =
Console.WriteLine("{0}{1} {2:#,0}", indent, name, count)
for kv in children do kv.Value.Show(indent + "| ")
do
use sr = new StreamReader(xml)
use xr = XmlReader.Create(sr)
let root = Node ""
root.Parse xr
printfn "%s" xml
printfn ""
root.Show()
このコードで実際に巨大な XML を分析してみます。
Wikipedia
Wikipedia は XML でダンプデータを提供しています。注意書きがあります。
ファイルサイズが巨大なため、解凍したXMLを通常のエディタやブラウザで開かないようにご注意ください。
日本語版だとあまりにも巨大過ぎるため、サイズが 1/10 ほどのエスペラント版を使用します。
eowiki-20200501-pages-articles-multistream.xml
mediawiki 1
| siteinfo 1
| | sitename 1
| | dbname 1
| | base 1
| | generator 1
| | case 1
| | namespaces 1
| | | namespace 29
| page 579,678
| | title 579,678
| | ns 579,678
| | id 579,678
| | revision 579,678
| | | id 579,678
| | | parentid 375,094
| | | timestamp 579,678
| | | contributor 579,678
| | | | username 573,158
| | | | id 573,158
| | | | ip 6,520
| | | minor 211,655
| | | comment 499,900
| | | model 579,678
| | | format 579,678
| | | text 579,678
| | | sha1 579,678
| | redirect 187,022
| | restrictions 50
約58万ページあることが分かりました。
※ 2週間ほどのずれがあるとは言え、統計ページの数字とは異なりますが、詳細は不明です。
- Wikipedia:全言語版の統計 - Wikipedia (2020年5月15日時点)
順位 言語 原語表記 / 英語記事 WP 純記事数 総項目数 ⋯ 34 エスペラント語 Esperanto eo 280,004 621,813 ⋯
なお、Wikipedia の実運用ではデータは MySQL に格納しているそうです。
関連記事
Wikipedia のダンプデータは圧縮したままデータが取り出せます。詳細は以下を参照してください。
多言語辞書 Wiktionary のダンプからデータを抽出する記事です。Wikipedia の関連プロジェクトでダンプの形式は同じです。