Clojureでxmlを読み込んで、clj-xpathで検索

日記「Clojureでxmlを読み込んで、zip-filterで検索 - oknknicの日記」では zip と zip-filter による xml 検索をした。
今回は、javax.xml をラップしたライブラリ clj-xpath を使ってみたのでメモ。

clj-xpath

  • project.clj の :dependencies に追加
[com.github.kyleburton/clj-xpath "1.4.1"]
  • サンプルファイル(in.xml)
<root>
  <records>
    <record id="1">record01</record>
    <record id="2">record02</record>
  </records>
  <record id="3">record03</record>
</root>
  • 実行例
(use 'clj-xpath.core)

;任意のrecordのテキスト
($x:text* "//record" "<root><records><record>rec01</record></records><record>rec02</record></root>")
;-> ("rec01" "rec02")

;任意のrecords直下のrecordのテキスト
($x:text* "//records/record" "<root><records><record>rec01</record></records><record>rec02</record></root>")
;-> ("rec01")

;任意のrecordのノード情報
($x "//record" "<root><records><record id=\"1\">rec01</record></records><record id=\"2\">rec02</record></root>")
;-> ({:children #<Delay@85a4506:  :pending>, :node #<DeferredElementImpl [record: null]>, :tag :record, :attrs {:id "1"}, :text "rec01"}
;    {:children #<Delay@5e699132: :pending>, :node #<DeferredElementImpl [record: null]>, :tag :record, :attrs {:id "2"}, :text "rec02"})

;任意のrecords直下の、任意のノードのノード情報
($x "//records/*" "<root><records><record id=\"1\">rec01</record></records><record id=\"2\">rec02</record></root>")
;-> ({:children #<Delay@7dbff9ea: :pending>, :node #<DeferredElementImpl [record: null]>, :tag :record, :attrs {:id "1"}, :text "rec01"})

;root以下の任意階層の、任意のノードのノード情報
($x "root//*" "<root><records><record id=\"1\">rec01</record></records><record id=\"2\">rec02</record></root>")
;-> ({:children #<Delay@1d8c3d92: :pending>, :node #<DeferredElementImpl [records: null]>, :tag :records, :attrs {}, :text "rec01"}
;    {:children #<Delay@621e4b65: :pending>, :node #<DeferredElementImpl [record: null]>, :tag :record, :attrs {:id "1"}, :text "rec01"}
;    {:children #<Delay@32e80636: :pending>, :node #<DeferredElementImpl [record: null]>, :tag :record, :attrs {:id "2"}, :text "rec02"})