ErlangでXML

30分プログラム、その427。ErlangXMLを使ってみる。
ErlangXMLをパースするには、標準添付のxmerlを使えばいいらしい。これでXMLをパースすると、以下のようなレコードになる。

-record(xmlElement,{
	  name,			% atom()
	  expanded_name = [],	% string() | {URI,Local} | {"xmlns",Local}
	  nsinfo = [],	        % {Prefix, Local} | []
	  namespace=#xmlNamespace{},
	  parents = [],		% [{atom(),integer()}]
	  pos,			% integer()
	  attributes = [],	% [#xmlAttribute()]
	  content = [],
	  language = "",	% string()
	  xmlbase="",           % string() XML Base path, for relative URI:s
	  elementdef=undeclared % atom(), one of [undeclared | prolog | external | element]
	 }).

これからパターンマッチを使って要素を抽出できるんだけど、割とつらいのでXPathが使いたいなぁ、とちょっと思ったり。

使い方

同じディレクトリにrssというファイルを置いた上で実行する。

$ erl -noshell -s xml main -s init stop
[本]”ミニ実験でつかむパケット解析手法 ネットワーク原理の観察からトラブルシ ューティングまで”を読み終わったよ
”Crossfire for Firefox”を書いた人がブログを始めました
[Linux][メモ]HP2133にUbuntu/Ratpoisonを入れるためのメモ
[Ruby][30分プログラム]バッテリーの残量表示
[Haskell][30分プログラム]ならしコストによるQueue
[日記]IDがOSの名前の人にブックマークされた!
[Scala][30分プログラム]Fuzzing用ファイルジェネレータ
AlchemyはLLVMをAS3に変換してるらしい
[日記]Gauche-FUSEを試してみた
[Scheme][30分プログラム]文字のヒストグラム

ソースコード

% http://muharem.wordpress.com/2007/08/21/processing-xml-in-erlang/
-module(xml).
-compile([export_all]).
-include_lib("/opt/local/lib/erlang/lib/xmerl-1.1.9/include/xmerl.hrl").

titles(#xmlElement{name='rdf:RDF', content=Contents})  ->
    lists:flatmap(
      fun (Child) -> 
	      case Child of
		  #xmlElement{name='item',content= Item} ->
		      lists:flatmap(
			fun (X) ->
				case X of
				    #xmlElement{name='title',
						content=[#xmlText{value=T}]} ->
					[T];
				    _ ->
					[]
				end
			end,Item);
		  _ ->
		      []
	      end
      end,
      Contents).
    
main() ->
    {R,_} = xmerl_scan:file("rss"),
    lists:foreach(fun(T) -> io:format("~s~n",[T]) end,
		  titles(R)).