2009年11月2日作成
xpathコマンド
Plan 9に移植されたPythonで、 XPath検索するコマンドを作りました。 文字コードの関係で4時間ほど悩んだことを除けば、お手軽でいい言語ですね。 文字コードの問題については、PythonのUnicodeEncodeErrorを知るが よくまとまっている資料だと思います。
まず、以下のソースをXPath.pyとして保存。
#!/bin/python
import sys, codecs
from BSXPath import BSXPathEvaluator as XPathEvaluator
from BSXPath import XPathResult
def find(xpath, fin, fname):
lines = fin.readlines()
data = ''.join(lines)
try:
doc = XPathEvaluator(data)
r = doc.getItemList(xpath)
except TypeError, e:
print >>sys.stderr, "xpath: '%s' %s" % (fname, e)
return 0
except ValueError, e:
print >>sys.stderr, "xpath: '%s' %s" % (fname, e)
return 0
n = len(r)
for i in range(n):
if isinstance(r[i], unicode):
print r[i]
elif 'decode' not in dir(r[i]):
print r[i]
else:
print r[i].decode('utf-8')
return n
sys.stdin = codecs.lookup('utf_8')[-1](sys.stdin)
sys.stdout = codecs.lookup('utf_8')[-1](sys.stdout)
argv = sys.argv[1:]
xpath = argv[0]
argv.pop(0)
found = 0
if len(argv) == 0:
found += find(xpath, sys.stdin, None)
else:
for f in argv:
fin = open(f, 'r')
found += find(xpath, fin, f)
fin.close()
if found == 0:
exit(1)
以下2つのモジュールをXPath.pyと同じ場所に置きます。
最後にxpathを呼び出すシェルスクリプト。
#!/bin/rc
if(~ $#* 0){
echo 'usage: xpath pattern [files]' >[1=2]
exit usage
}
exec python /bin/_xpath/XPath.py $*
まとめ。
/bin/xpath
/bin/_xpath/BeautifulSoup.py
/bin/_xpath/BSXPath.py
/bin/_xpath/XPath.py