sxml.css-sxpathで :nth-child(an+b) をサポート

これまでsxml.css-sxpathの:nth-child()では:nth-child(2)のように単純なインデックス指定のみ有効でしたが、:nth-child(2n+1)とか:nth-child(even)のような記法もサポートするようにしてみました。バージョン0.2としてリリースします。

インストール

gauche-packageコマンドでインストールできます。
githubはこちら GitHub - teppey/Gauche-sxml-css-sxpath: CSS3 Selector to SXPath Converter

$ gauche-package install [-S root] https://github.com/downloads/teppey/Gauche-sxml-css-sxpath/Gauche-sxml-css-sxpath-0.2.tgz

使い方

(define html
  '(*TOP*
    (html
      (body
        (ul
          (li "1")
          (li "2")
          (li "3")
          (li "4")
          (li "5")
          (li "6"))))))

 ((css-sxpath "li:nth-child(2n)") html)     ;=> ((li "2") (li "4") (li "6"))
 ((css-sxpath "li:nth-child(even)") html)   ;=> ((li "2") (li "4") (li "6"))
 ((css-sxpath "li:nth-child(2n+1)") html)   ;=> ((li "1") (li "3") (li "5"))
 ((css-sxpath "li:nth-child(odd)") html)    ;=> ((li "1") (li "3") (li "5"))
 ((css-sxpath "li:nth-child(3n+2)") html)   ;=> ((li "2") (li "5"))

evenは2n、oddは2n+1と同じ意味になります。

text.jsonをリリース

※ 0.2を出しました

JSONを読み書きするGaucheモジュールを書きました。すでにtrunkにはrfc.jsonというのが入っていて、そう遠くない未来にリリースされると思うんですが*1、まあそれまでのつなぎとして。コードはgithubにあります。

http://github.com/teppey/Gauche-text-json/

インストール

gauche-packageにパッケージのURLを渡すのが簡単です。

$ gauche-package install [-S root] http://github.com/downloads/teppey/Gauche-text-json/Gauche-text-json-0.1.tgz

使用例

$ cat books.json
[
    { "title": "星を継ぐもの",
      "author": "J・P・ホーガン",
      "price": 660 },

    { "title": "北壁の死闘",
      "author": "ボブ・ラングレー",
      "price": 900 },

    { "title": "旅のラゴス",
      "author": "筒井康隆",
      "price": 438 }
]
$ gosh
gosh> (use text.json)
#<undef>
gosh> (define json (with-input-from-file "./books.json" json-read))
json
gosh> (use slib)
#<undef>
gosh> (require 'pretty-print)
#t
gosh> (pretty-print json)
#((("title" . "星を継ぐもの")
   ("author" . "J・P・ホーガン")
   ("price" . 660))
  (("title" . "北壁の死闘")
   ("author" . "ボブ・ラングレー")
   ("price" . 900))
  (("title" . "旅のラゴス")
   ("author" . "筒井康隆")
   ("price" . 438)))
21
gosh> (ref json 0)
(("title" . "星を継ぐもの") ("author" . "J・P・ホーガン") ("price" . 660))
gosh> (json-write (ref json 0) #f)
"{\"title\":\"\\u661F\\u3092\\u7D99\\u3050\\u3082\\u306E\",\"author\":\"J\\u30FBP\\u30FB\\u30DB\\u30FC\\u30AC\\u30F3\",\"price\":660}"
gosh> (json-read (json-write (ref json 0) #f))
(("title" . "星を継ぐもの") ("author" . "J・P・ホーガン") ("price" . 660))
gosh>

よかったらお使いください。

*1:追記: 0.9.1で入りました

sxml.css-sxpathというモジュールを書きました

sxpathでは専用のクエリ言語・手続き・XPathを使ってSXMLからノードを選択することができますが、合わせてCSSセレクタも扱えるようなモジュールを書きました。

インストール

Gauche-sxml-css-sxpath-0.1.tgzをダウンロードしてgauche-packageコマンドでインストールできます。

    $ gauche-package install [-S root] Gauche-sxml-css-sxpath-0.1.tgz

もしくはgithubからgit cloneしてください。

$ git clone git://github.com/teppey/Gauche-sxml-css-sxpath.git
$ cd Gauche-sxml-css-sxpath
$ ./DIST gen
$ ./configure
$ make
$ make -s check
$ [sudo] make install

使い方

(define html
  '(*TOP*
     (html
       (head
         (title "Hello"))
       (body
         (h1 (@ (id "header")) "Hello, world")
         (p (@ (align "center")) "lorem ipsum")
         (ul
          (li (@ (class "foo")) "abc")
          (li (@ (class "bar")) "123"))
         (a (@ (href "http://example.com")) "quux")))))


;IDセレクタ, クラスセレクタ
((css-sxpath "#header") html) ; => ((h1 (@ (id "header")) "Hello, world"))
((css-sxpath "li.bar") html)  ; => ((li (@ (class "bar")) "123"))


;属性セレクタ
((css-sxpath "p[align='center']") html) ; => ((p (@ align "center") "lorem ipsum"))


;疑似クラス
((css-sxpath "ul li:first-child") html) ; => ((li (@ (class "foo")) "abc"))
((css-sxpath "ul li:nth-child(2)") html) ; => ((li (@ (class "bar")) "123"))


;セレクタグループ
((css-sxpath "head > title , a") html) ; => ((title "hello") (a (@ (href "http://example.com")) "quux"))


;SXPathのクエリ言語やXPathと一緒に使うこともできます。
((css-sxpath '("ul li.bar" *text*)) html)            ; => ("123")
((css-sxpath '("//body//ul" "li:first-child")) html) ; => ((li (@ (class "foo")) "abc"))


;接頭辞つきの要素名を指定するときは、":"をバックスラッシュでエスケープします。
((css-sxpath "rss\\:title") '(*TOP* (rss:title "hocus pocus"))) ; => ((rss:title "hocus pocus"))


;sxpathと同様なラッパ関数もあります。
((car-css-sxpath '("ul li.bar" *text*)) html) ; => "123"
((if-css-sxpath "body blockquote") html) ; => #f


さらに詳しい説明はREADME.jaにあります。よかったら使ってみてください。

謝辞

以下に挙げるWebサイトやコードを参考にしました。ありがとうございます。

CSS3 Selectors

SXPath

HTML::Selector::XPath - search.cpan.org

CSS3セレクタとXPathでの表現の対応表