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を操作する大まかな材料はそろったかと思います。

今度、コレクションに登録してあるドキュメントを全て抜き出し、
ファイルに吐き出す、バックアップ用のプログラムを考えて見ます。



もどる