【问题标题】:querySelector in Apache BatikApache Batik 中的 querySelector
【发布时间】:2013-01-19 07:23:48
【问题描述】:

我想在 Apache Batik DOM 中查询与 CSS 选择器匹配的元素。

Batik 是否提供以下任何浏览器 DOM 方法的替代方法?

【问题讨论】:

    标签: css dom batik


    【解决方案1】:

    好的,这是我设法整合的解决方案。它是用 Clojure 而不是 Java 编写的,但重要的是:

    1. 实例化 org.apache.batik.css.engine.sac.CSSConditionFactory
    2. 实例化 org.apache.batik.css.parser.Parser
    3. 调用 Parser.parseSelectors
    4. 调用 org.apache.batik.dom.traversal.TraversalSupport.createNodeIterator
    5. 在您的 NodeFilter 中,遍历已解析的 SelectorList,调用 ExtendedSelector.match
    6. 有条件地跳过从迭代器返回的第一个节点(它始终是遍历根)
    (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)))))
    

    【讨论】:

      猜你喜欢
      • 2018-03-28
      • 1970-01-01
      • 1970-01-01
      • 2016-11-09
      • 1970-01-01
      • 2018-06-17
      • 2019-10-03
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多