読者です 読者をやめる 読者になる 読者になる

ちょっとハマったので、ErlangのXML処理のメモ

元ネタは2007年ごろのerlang-questionのMLで「ErlangXML処理なんてどうやったらいいんだ?(結構同感な私)」という問いかけに対する応答としてコードが寄せられたもの。
それを記事にしてくれたのがtornkvistさん
それらを

  • parseの仕方として
    • 全部いっぺんに処理するもの
    • SAX的に逐次処理するもの、
  • 結果のトラバースの仕方として
    • 独自のロジックを実装するもの
    • xpathなどを利用するもの

という分類などをしてみて、自分が使うかなぁ、と思えた3つのケースについてコードを書いてみた。もちろん独自のひねりなどはナシ。初心者の習字。

あとは、英文だけど、私のポストを見てください(手抜きですみません)
ErlangもR13Bあたりからxmerl_sax_parserのライブラリが添付されるようになったので、SAXのケースについてはそちらを使っています。世の中ではerlsom_saxというのがメジャーみたい。というわけで、そのケースだけ、コードをこちらにも貼っておきます。このコードではattributeとかは処理してません(そういうサンプルデータを処理するのがネタだったので)

-module(example3).
-export([go/1]).

go(File) ->
        Option = [
                {event_fun, fun eventfun/3},
                {event_state, {[], []}}
                ],
        case xmerl_sax_parser:file(File, Option) of
                {ok,{_Stack, Acc}} -> lists:reverse(Acc);
                {ok, Bin} -> Bin;
                {Other} -> Other
        end
        .

eventfun({ignorableWhitespace, _}, _, State) ->
        State
        ;
eventfun({startElement, _, Tag, _, _}, _Location, {Stack, Acc}) ->
        {[Tag | Stack], Acc}
        ;
eventfun({characters, Value}, _Location, {[Tag | _L] = Stack, Acc}) ->
        {Stack, [{Tag, Value} | Acc]}
        ;
eventfun({endElement, _, _, _, _}, _Location, {[_ | L], Acc}) ->
        {L, Acc}
        ;
eventfun(_,_,State) ->
        State
        .