Skip to content
This repository has been archived by the owner on Oct 7, 2024. It is now read-only.

Commit

Permalink
Query select (#98)
Browse files Browse the repository at this point in the history
* get tag

* tag, attr, init

* works

* move to ns

* ref

* make axelf compartable

* comment

* some simple tests
  • Loading branch information
zarkone authored Mar 19, 2020
1 parent 2806ecd commit 3c1e988
Show file tree
Hide file tree
Showing 3 changed files with 89 additions and 0 deletions.
50 changes: 50 additions & 0 deletions src/axel_f/excel/query_select.cljc
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
(ns axel-f.excel.query-select
(:require [clojure.string :as string]))

(def children (mapcat #(get % "children")))

(defn tag= [{:keys [tag]}]
(filter #(= tag (get % "tag"))))

(defn attr= [{:keys [attr value]}]
(if (some? attr)
(filter #(= value
(get-in % ["attrs" attr])))
identity))

(defn parse-item [item]
(if-some [[_ tag attr value] (re-matches #"(.*)\[(.*)=(.*)\]" item)]
{:tag tag
:attr attr
:value value}
{:tag item}))

(defn make-tag-getter [query]
(->> (string/split query #"\.")
(map parse-item)
(map #(comp (tag= %) (attr= %) children))
(apply comp)))

(defn query-select [items query]
(let [query (or query "")
tag-getter (make-tag-getter query)]
(sequence tag-getter items)))

(defn QUERYSELECT*
"Perform querySelector-like query on collection of items"
[^{:doc "Object representaiton of xml-like structure"} item
^{:doc "Query to perform on `item`"} query]
(let [items (if (sequential? item) item [item])]
(query-select items query)))

(def QUERYSELECT #'QUERYSELECT*)

(def env
{"QUERYSELECT" QUERYSELECT})

(comment
(let [_ "<?xml version= \"1.0\"?><response><id-number>2716902077</id-number><summary-result><key>id.success</key><message>PASS</message></summary-result><results><key>result.match</key><message>ID Located</message></results></response>"
parsed2 {"tag" "response","attrs" {"foo" "bar"} "children" [{"tag" "id-number", "children" ["2716902077\n "]} {"tag" "summary-result", "children" [{"tag" "key", "children" ["id.success\n "]} {"tag" "message", "children" ["PASS"]} {"tag" "message", "children" ["PASS22"]}]} {"tag" "results", "children" [{"tag" "key", "children" ["result.match\n "]} {"tag" "message", "children" ["ID Located\n "]}]}]}
items [parsed2]
query "response[foo=bar].summary-result.message"]
(query-select items query)))
2 changes: 2 additions & 0 deletions src/axel_f/excel_lite.cljc
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
[axel-f.excel.coerce :as coerce]
[axel-f.excel.operators :as operators]
[axel-f.excel.collections :as collections]
[axel-f.excel.query-select :as query-select]
[axel-f.excel.geo :as geo]
[axel-f.excel.logic :as logic]
[axel-f.excel.math :as math]
Expand All @@ -17,6 +18,7 @@
(def base-env
(merge
operators/env
query-select/env
collections/env
geo/env
logic/env
Expand Down
37 changes: 37 additions & 0 deletions test/axel_f/query_select_test.cljc
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
(ns axel-f.query-select-test
(:require #?(:clj [clojure.test :as t]
:cljs [cljs.test :as t :include-macros true])
[axel-f.excel :as af]))

(t/deftest query-select
(let [xml {"tag" "response","attrs" {"foo" "bar"} "children" [{"tag" "id-number", "children" ["2716902077\n "]} {"tag" "summary-result", "children" [{"tag" "key", "children" ["id.success\n "]} {"tag" "message", "children" ["PASS"]} {"tag" "message", "children" ["PASS22"]}]} {"tag" "results", "children" [{"tag" "key", "children" ["result.match\n "]} {"tag" "message", "children" ["ID Located\n "]}]}]}]
(t/is (= ["PASS" "PASS22"]
((af/compile "QUERYSELECT(xml, query)"
{"query" "response[foo=bar].summary-result.message"
"xml" xml}))))
(t/is (= ["PASS" "PASS22"]
((af/compile "QUERYSELECT(xml, query)"
{"query" "response.summary-result.message"
"xml" xml}))))
(t/is (= [{"tag" "key", "children" ["id.success\n "]}
{"tag" "message", "children" ["PASS"]}
{"tag" "message", "children" ["PASS22"]}]
((af/compile "QUERYSELECT(xml, query)"
{"query" "response.summary-result"
"xml" xml}))))
(t/is (= []
((af/compile "QUERYSELECT(xml, query)"
{"query" nil
"xml" xml}))))
(t/is (= []
((af/compile "QUERYSELECT(xml, query)"
{"query" "doesnt.exist"
"xml" xml}))))
(t/is (= []
((af/compile "QUERYSELECT(xml, query)"
{"query" "doesnt.exist"
"xml" xml}))))
(t/is (= []
((af/compile "QUERYSELECT(xml, query)"
{"query" "failed[fuuuuu.query"
"xml" xml}))))))

0 comments on commit 3c1e988

Please sign in to comment.