CSSセレクターに一致する要素についてApacheBatikDOMにクエリを実行したいと思います。
Batikは、次のブラウザDOMメソッドのいずれかに代わるものを提供しますか?
CSSセレクターに一致する要素についてApacheBatikDOMにクエリを実行したいと思います。
Batikは、次のブラウザDOMメソッドのいずれかに代わるものを提供しますか?
OK、これが私がまとめた解決策です。Java ではなく Clojure で書かれていますが、重要な点は次のとおりです。
(def ^:private condition-factory
(CSSConditionFactory. nil "class" nil "id"))
(defn- parse-selector [selector]
(let [parser (Parser.)]
(doto parser
(.setSelectorFactory CSSSelectorFactory/INSTANCE)
(.setConditionFactory condition-factory))
(.parseSelectors parser selector)))
(defn- matches?
([selector element] (matches? selector element ""))
([selector element pseudo]
(let [length (.getLength selector)]
(loop [i 0]
(if (< i length)
(if (.. selector (item i) (match element pseudo))
true
(recur (inc i)))
false)))))
(defn selection-seq [root selector]
(let [selector (parse-selector selector)
iterator (.createNodeIterator (TraversalSupport.)
(.getOwnerDocument root)
root
NodeFilter/SHOW_ELEMENT
(reify NodeFilter
(acceptNode [_ element]
(if (matches? selector element)
NodeFilter/FILTER_ACCEPT
NodeFilter/FILTER_REJECT)))
false)
node-seq ((fn step []
(lazy-seq
(when-let [node (.nextNode iterator)]
(cons node (step))))))]
;; Iterator always returns the reference node, so match it.
(when-let [node (first node-seq)]
(if (matches? selector (first node-seq))
node-seq
(next node-seq)))))