2007年1月28日日曜日

FePyのElementPathモジュール

IronPythonでFePyのElementTreeモジュールを使用するときにXPathがうまく使えないということを以前に説明しました。これは正規表現のreモジュールの実装の違いであると説明しました。
具体的には、ElementPathはXPathを分解するのにre.filndall()メソッドを使ってリストの要素としてタプルが含まれていることを期待しているのですが、IronPython 1.0.1のre.findall()メソッドはリストのみを返すためにエラーとなります。
この現象を回避するために、ElementPathモジュールをxpath_tokenizerをIPCEかIronPythonかで正規表現の扱いかたを変更する必要があります。それには、以下のようにElementPathを書き換える必要があります。


##

# Deference IronPython-1.0.1 and IPCE-r5

# IPCE-r5 re.findall return a list includes tuple

# IP-1.0.1 re.findall return a list only

## 正規表現をコンパイルします

_token_pattern = re.compile(

"(::|\.\.|\(\)|[/.*:\[\]\(\)@=])|((?:\{[^}]+\})?[^/:\[\]\(\)@=\s]+)|\s+")

# When use IPY 1.0.1, return True

# IronPython 1.0.1 の正規表現かどうかをテストします

def _check_ipy():

ret = _token_pattern.findall("/root/test")

itm = ret[0]

if isinstance(itm, tuple): return False

return True

## for IPY 1.0.1 Only

## IronPython 1.0.1の場合に呼び出される関数を定義します

def _ipy_tokennizer(xpath):

return [m.groups() for m in _token_pattern.finditer(xpath)]



xpath_tokenizer = _token_pattern.findall

## IronPython 1.0.1なら呼び出し先を関数に変更します

if _check_ipy():

xpath_tokenizer = _ipy_tokennizer

##

# original code 以下は、元のオリジナルなコードです

#xpath_tokenizer = re.compile(

# "(::|\.\.|\(\)|[/.*:\[\]\(\)@=])|((?:\{[^}]+\})?[^/:\[\]\(\)@=\s]+)|\s+"

# ).findall

##

上記のように変更すれば、IronPython 1.0.1でもXPath式が利用できるようです。

0 件のコメント: