Let's start Scheme

2012-01-06

sxpathメモ

SXPathで名前空間付のSXMLにクエリーを発行するのがいまいち分からなかったのでメモ。
正直これが正しいのか良く分かっていない。
(import (text sxml ssax) (text sxml sxpath) (pp))
(define *xml* "<?xml version=\"1.0\" ?><root xmlns:h=\"http://localhost/\"><h:p>hello</h:p></root>")
(define *namespace* '((h . "http://localhost/")))
(let ((sxml (ssax:xml->sxml (open-string-input-port *xml*) *namespace*))
      (sxml2 (ssax:xml->sxml (open-string-input-port *xml*) '())))
  (pp sxml)
  (pp sxml2)
  (let ((doc ((sxpath '(root h:p)) sxml))
       (doc2 ((sxpath '(root h:p) *namespace*) sxml2)))
    (pp doc)
    (pp doc2)))
#|
(*TOP* (@ (*NAMESPACES* (h "http://localhost/")))
       (*PI* xml "version=\"1.0\" ")
       (root (h:p "hello")))
(*TOP* (*PI* xml "version=\"1.0\" ")
       (root (http://localhost/:p "hello")))
((h:p "hello"))
()
|#
パース時に名前空間を与えてやるとタグをプレフィックス付でパースする。与えないとそのまま長い名前で出力する。
プレフィックス付のSXMLをsxpathに渡すなら、名前空間は要らない(あってもよい)。
プレフィックスなしをsxpathに渡すなら長い名前で指定する必要がある。名前空間渡しても識別しない。
ここに使い方があった。
Re: SXPath namespaces - msg#00006
どうやらsxpathの第二引数は微妙な動作をするくさい。上記の例だと
(pp ((sxpath "//root/h:p" *namespace*) sxml2))
#|
((http://localhost/:p "hello"))
|#
これで通る。S式なクエリでは認識しないが文字列ならOK。いまいちssaxとの相性が悪いというか、完全別モジュールという感じだ。

No comments:

Post a Comment