Blog

node.js で libxml を使うにはどのライブラリをつかうべきか

目的

node.js で libxml をつかおうとすると、どれをつかっていいのかわからないので、どれがいいかを評価する。

XML をパーズするという用途はもちろんのこと、HTML のパーズなどにくらべても、pure JS のものよりも高速に動作するという予想が長年の経験より想像されますので、そういった意味でもしらべておきたいところです。

実験方法

ためしたプラットホームは OSX lion です。 homebrew つかってます。

npm search libxml してでてきたものを対象としてしらべます。

% npm search libxml
libxml        libxml2 wrapper for node.js                                   =fja
libxml-to-js  XML to JavaScript object parser based on libxmljs             =sal
libxmlext     Extensions to libxmljs to add CSS XPath selectors             =eug
libxmljs      libxml bindings for v8 javascript engine                      =pol

実験結果

libxmljs

これが結局本命です。普通につかいやすいです。
ドキュメンテーションとかはちょっとあまいかも。

elem.text('string') したいけどドキュメントには Getter ってかいてあるなーとおもってたけどソースよんだら Setter も用意されてた!
みたいなのが普通にある。

libxml-to-js

XML to JavaScript object parser based on libxmljs なので、そもそも求めているものとちがいます。
Perl でいうと XML::Simple にちかいものです。XML::Simple がほしいときならアリかも。

そしてこれは libxmljs のラッパーです。

libxmlext

libxmljs に css selector の機能を追加するものなようです。libxmlext/node_modules/ 以下に libxmljs がはいってます。これは便利!
だけど、node_modules/ 以下にはいってるのちょっと古いやつなので、モジュールとかでこれに依存する場合には libxmljs を別途 deps にいれてインストールさせた方がいいのかも?

そしてこれは libxmljs のラッパーです。

libxml

コンパイルが通らないので論外です。

> [email protected] preinstall /Users/tokuhirom/node_modules/libxml
> ./build.sh

The "sys" module is now called "util". It should have a similar interface.
Checking for program g++ or c++          : /usr/bin/g++ 
Checking for program cpp                 : /usr/bin/cpp 
Checking for program ar                  : /usr/bin/ar 
Checking for program ranlib              : /usr/bin/ranlib 
Checking for g++                         : ok  
Checking for node path                   : not found 
Checking for node prefix                 : ok /usr/local/Cellar/node/0.6.6 
'configure' finished successfully (0.040s)
Waf: Entering directory `/Users/tokuhirom/node_modules/libxml/support/o3/build'
[1/3] cxx: hosts/node-o3/sh_node.cc -> build/Release/hosts/node-o3/sh_node_1.o
13:23:47 runner system command -> ['/usr/bin/g++', '-g', '-O3', '-msse2', '-ffast-math', '-fPIC', '-compatibility_version', '1', '-current_version', '1', '-D_LARGEFILE_SOURCE', '-D_FILE_OFFSET_BITS=64', '-D_GNU_SOURCE', '-IRelease', '-I..', '-IRelease/include', '-I../include', '-IRelease/hosts', '-I../hosts', '-IRelease/modules', '-I../modules', '-IRelease/deps', '-I../deps', '-I/usr/local/Cellar/node/0.6.6/include/node', '../hosts/node-o3/sh_node.cc', '-c', '-o', 'Release/hosts/node-o3/sh_node_1.o']
[2/3] cxx: hosts/node-o3/sh_node_libs.cc -> build/Release/hosts/node-o3/sh_node_libs_1.o
13:23:47 runner system command -> ['/usr/bin/g++', '-g', '-O3', '-msse2', '-ffast-math', '-fPIC', '-compatibility_version', '1', '-current_version', '1', '-D_LARGEFILE_SOURCE', '-D_FILE_OFFSET_BITS=64', '-D_GNU_SOURCE', '-IRelease', '-I..', '-IRelease/include', '-I../include', '-IRelease/hosts', '-I../hosts', '-IRelease/modules', '-I../modules', '-IRelease/deps', '-I../deps', '-I/usr/local/Cellar/node/0.6.6/include/node', '../hosts/node-o3/sh_node_libs.cc', '-c', '-o', 'Release/hosts/node-o3/sh_node_libs_1.o']
[3/3] cxx_link: build/Release/hosts/node-o3/sh_node_1.o build/Release/hosts/node-o3/sh_node_libs_1.o -> build/Release/o3.node
13:24:09 runner system command -> ['/usr/bin/g++', 'Release/hosts/node-o3/sh_node_1.o', 'Release/hosts/node-o3/sh_node_libs_1.o', '-o', '/Users/tokuhirom/node_modules/libxml/support/o3/build/Release/o3.node', '-bundle', '-undefined', 'dynamic_lookup', '-L/usr/local/Cellar/node/0.6.6/lib', '-lxml2']
Waf: Leaving directory `/Users/tokuhirom/node_modules/libxml/support/o3/build'
'build' finished successfully (22.995s)
cp: cannot stat `build/default/o3.node': No such file or directory
npm ERR! error installing [email protected] Error: [email protected] preinstall: `./build.sh`
npm ERR! error installing [email protected] `sh "-c" "./build.sh"` failed with 1
npm ERR! error installing [email protected]     at ChildProcess.<anonymous> (/usr/local/lib/node_modules/npm/lib/utils/exec.js:49:20)
npm ERR! error installing [email protected]     at ChildProcess.emit (events.js:70:17)
npm ERR! error installing [email protected]     at maybeExit (child_process.js:359:16)
npm ERR! error installing [email protected]     at Process.onexit (child_process.js:395:5)
npm ERR! [email protected] preinstall: `./build.sh`
npm ERR! `sh "-c" "./build.sh"` failed with 1
npm ERR! 
npm ERR! Failed at the [email protected] preinstall script.
npm ERR! This is most likely a problem with the libxml package,
npm ERR! not with npm itself.
npm ERR! Tell the author that this fails on your system:
npm ERR!     ./build.sh
npm ERR! You can get their info via:
npm ERR!     npm owner ls libxml
npm ERR! There is likely additional logging output above.
npm ERR! 
npm ERR! System Darwin 11.2.0
npm ERR! command "node" "/usr/local/bin/npm" "install" "libxml"
npm ERR! cwd /Users/tokuhirom/tmp/20111223
npm ERR! node -v v0.6.6
npm ERR! npm -v 1.0.106
npm ERR! code ELIFECYCLE
npm ERR! 
npm ERR! Additional logging details can be found in:
npm ERR!     /Users/tokuhirom/tmp/20111223/npm-debug.log
npm not ok

まとめ

libxmljs を基本的につかう。

CSS Selector をつかいたい場合には libxmlext をつかってもよい。
XML::Simple 的に JS の構造に変換したものをつかいたい場合には libxml-to-js です。

【蛇足: これはおうおもう】
libxml ひとつとっても、ぶっこわれたものがあったりして罠い。