Python eXist(XMLDB)にxmlrpcで接続する
eXistという(個人的には)有名なXMLDBがあります。
http://exist.sourceforge.net/
以前、JavaでeXistに接続してサンプルアプリケーションを
作成したことがあるのですが
http://fujishinko.nengu.jp/exist/index.html
調べてみると、SOAPやxmlrpcで接続し、操作できるようです。
eXistのサイトにxmlrpc接続のサンプル(perl)があったので、
Pythonで試してみました。
http://exist.sourceforge.net/devguide_xmlrpc.html
※APIの仕様が変更されているようで、
一部本家のドキュメントと一致しない箇所があります。
ちなみに、eXistのバージョンは「1.2.4-rev8072」で
試しています。
1. Using the XML-RPC API
Pythonでxmlrpc通信を行うには、「xmlrpclib」を使用します。
eXistに接続するにはこんな感じ
import xmlrpclib
xmlrpc_url = 'http://www.example.com:8080/exist/xmlrpc'
#adminのパスワードを登録している場合は以下の通り
#xmlrpc_url = 'http://admin:password@www.example.com:8080/exist/xmlrpc'
#通信用のオブジェクトを生成
srv = xmlrpclib.ServerProxy(xmlrpc_url)
2.1. Retrieving documents
getDocumentAsStringで、xmlドキュメントが取得できます。
/db/sampleコレクションにtest.xmlという名前でドキュメントを
登録している場合
import xmlrpclib
xmlrpc_url = 'http://www.example.com:8080/exist/xmlrpc'
srv = xmlrpclib.ServerProxy(xmlrpc_url)
print srv.getDocumentAsString('/db/sample/test.xml', {})
上記のソースコードでtest.xmlの内容が表示されます。
※ちなみに、ドキュメントの指定は
/sample/test.xml
sample/test.xml
でもOKでした。
また、
result = srv.getDocumentData('sample/test.xml',{})
print result['data']
print result['offset']
としても、ドキュメントの取得が行えます。
多分、getNextChunkと組み合わせて、連続的にデータの
取得が行えると思うのですが、いまいち使い方がわかってません。(^^;
2.2. Storing Documents
データをサーバに保存する方法です。
RDBで言うところのinsertでしょうか。
import xmlrpclib
xmlrpc_url = 'http://www.example.com:8080/exist/xmlrpc'
srv = xmlrpclib.ServerProxy(xmlrpc_url)
data = u"""<data>
<demo no="0000000002">
<value>テストデータ2</value>
</demo>
</data>"""
srv.parse(data, 'sample/test2.xml')
これで、/db/sampleコレクションにtest2.xmlという名前で
ドキュメントが追加されます。
既にtest2.xmlという名前のドキュメントが存在する場合は、
xmlrpclib.Fault: <Fault 0: 'org.exist.security.PermissionDeniedException: Docume
nt exists and overwrite is not allowed'>
というエラーが発生し、登録に失敗します。
自動的に上書きさせたい場合には、
srv.parse(data, 'sample/test2.xml', 1)
第三引数に0より大きい値を指定すると、同じ名前のドキュメントが
存在する場合には自動的に上書きされます。
2.3. Creating a Collection
コレクションの作成を行います。
RDBで言うところのcreate tableでしょうか。
srv.createCollection('sample')
これだけで、/db/sampleコレクションが作成されます。
2.4. Removing Documents or Collections
ドキュメントとコレクションの削除方法です。
#ドキュメント削除
srv.remove('sample/test2.xml')
#コレクション削除
srv.removeCollection('sample')
2.5. Querying
xqueryの発行方法です。
気をつけないといけないのは、queryを発行したらその結果が
返されるのではなく、発行結果のIDが帰ってきます。
そのIDを元に、今度は実行結果を取得するメソッドを使用して
結果を見ます。
最後に、不要となった実行結果をリリースしてあげます。
ソースコードだとこんな感じ
import xmlrpclib
xmlrpc_url = 'http://www.example.com:8080/exist/xmlrpc'
srv = xmlrpclib.ServerProxy(xmlrpc_url)
#base-uriを指定し、検索範囲を/db/sampleコレクションに限定
result_id = srv.executeQuery("//data", {'base-uri':'/db/sample/'})
#ヒットしたドキュメント数
print srv.getHits(result_id)
#実行結果の概要を取得
result_set = srv.querySummary(result_id)
#getHitsと同じ意味
print 'hits',result_set['hits']
#検索実行時間
print 'queryTime',result_set['queryTime']
#ドキュメントの形式
print 'doctypes',result_set['doctypes']
#該当したドキュメントのデータリスト
for doc in result_set['documents']:
#ドキュメントの名称
print 'document name',doc[0]
#ドキュメントのID
print 'document id',doc[1]
#ドキュメントに検索条件とのマッチがいくつ含まれるか
print 'document match',doc[2]
#検索結果をまとめて表示(xml形式)
print srv.retrieveAll(result_id,{})
#検索結果を破棄
print srv.releaseQueryResult(result_id)
まずは、
・executeQueryでxpathを実行
帰ってきたIDを使用して
・getHits(result_id)でヒット数を取得
・querySummary(result_id)でヒットしたドキュメントの情報を取得
・retrieveAll(result_id)で検索結果のxmlを取得
最後に
・releaseQueryResult(result_id)で検索結果の破棄
という流れになります。
2.7. XUpdate
うーん。動かない・・・
以前作成したアプリケーションはXUpdateするのが面倒だったので、
remove->createとしていました。
なので、今回はスルーすることにします。
これで、eXistを操作する大まかな材料はそろったかと思います。
今度、コレクションに登録してあるドキュメントを全て抜き出し、
ファイルに吐き出す、バックアップ用のプログラムを考えて見ます。
もどる