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

Commit 3c1e988

Browse files
authored
Query select (#98)
* get tag * tag, attr, init * works * move to ns * ref * make axelf compartable * comment * some simple tests
1 parent 2806ecd commit 3c1e988

File tree

3 files changed

+89
-0
lines changed

3 files changed

+89
-0
lines changed

src/axel_f/excel/query_select.cljc

+50
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
(ns axel-f.excel.query-select
2+
(:require [clojure.string :as string]))
3+
4+
(def children (mapcat #(get % "children")))
5+
6+
(defn tag= [{:keys [tag]}]
7+
(filter #(= tag (get % "tag"))))
8+
9+
(defn attr= [{:keys [attr value]}]
10+
(if (some? attr)
11+
(filter #(= value
12+
(get-in % ["attrs" attr])))
13+
identity))
14+
15+
(defn parse-item [item]
16+
(if-some [[_ tag attr value] (re-matches #"(.*)\[(.*)=(.*)\]" item)]
17+
{:tag tag
18+
:attr attr
19+
:value value}
20+
{:tag item}))
21+
22+
(defn make-tag-getter [query]
23+
(->> (string/split query #"\.")
24+
(map parse-item)
25+
(map #(comp (tag= %) (attr= %) children))
26+
(apply comp)))
27+
28+
(defn query-select [items query]
29+
(let [query (or query "")
30+
tag-getter (make-tag-getter query)]
31+
(sequence tag-getter items)))
32+
33+
(defn QUERYSELECT*
34+
"Perform querySelector-like query on collection of items"
35+
[^{:doc "Object representaiton of xml-like structure"} item
36+
^{:doc "Query to perform on `item`"} query]
37+
(let [items (if (sequential? item) item [item])]
38+
(query-select items query)))
39+
40+
(def QUERYSELECT #'QUERYSELECT*)
41+
42+
(def env
43+
{"QUERYSELECT" QUERYSELECT})
44+
45+
(comment
46+
(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>"
47+
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 "]}]}]}
48+
items [parsed2]
49+
query "response[foo=bar].summary-result.message"]
50+
(query-select items query)))

src/axel_f/excel_lite.cljc

+2
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
[axel-f.excel.coerce :as coerce]
55
[axel-f.excel.operators :as operators]
66
[axel-f.excel.collections :as collections]
7+
[axel-f.excel.query-select :as query-select]
78
[axel-f.excel.geo :as geo]
89
[axel-f.excel.logic :as logic]
910
[axel-f.excel.math :as math]
@@ -17,6 +18,7 @@
1718
(def base-env
1819
(merge
1920
operators/env
21+
query-select/env
2022
collections/env
2123
geo/env
2224
logic/env

test/axel_f/query_select_test.cljc

+37
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
(ns axel-f.query-select-test
2+
(:require #?(:clj [clojure.test :as t]
3+
:cljs [cljs.test :as t :include-macros true])
4+
[axel-f.excel :as af]))
5+
6+
(t/deftest query-select
7+
(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 "]}]}]}]
8+
(t/is (= ["PASS" "PASS22"]
9+
((af/compile "QUERYSELECT(xml, query)"
10+
{"query" "response[foo=bar].summary-result.message"
11+
"xml" xml}))))
12+
(t/is (= ["PASS" "PASS22"]
13+
((af/compile "QUERYSELECT(xml, query)"
14+
{"query" "response.summary-result.message"
15+
"xml" xml}))))
16+
(t/is (= [{"tag" "key", "children" ["id.success\n "]}
17+
{"tag" "message", "children" ["PASS"]}
18+
{"tag" "message", "children" ["PASS22"]}]
19+
((af/compile "QUERYSELECT(xml, query)"
20+
{"query" "response.summary-result"
21+
"xml" xml}))))
22+
(t/is (= []
23+
((af/compile "QUERYSELECT(xml, query)"
24+
{"query" nil
25+
"xml" xml}))))
26+
(t/is (= []
27+
((af/compile "QUERYSELECT(xml, query)"
28+
{"query" "doesnt.exist"
29+
"xml" xml}))))
30+
(t/is (= []
31+
((af/compile "QUERYSELECT(xml, query)"
32+
{"query" "doesnt.exist"
33+
"xml" xml}))))
34+
(t/is (= []
35+
((af/compile "QUERYSELECT(xml, query)"
36+
{"query" "failed[fuuuuu.query"
37+
"xml" xml}))))))

0 commit comments

Comments
 (0)