|
7 | 7 | [clojure.data.xml.protocols :refer [AsQName]])) |
8 | 8 |
|
9 | 9 | (export-api |
10 | | - name/parse-qname name/qname-uri name/qname-local name/qname name/to-qname |
11 | | - node/element* node/element node/cdata node/xml-comment) |
| 10 | + name/parse-qname name/qname-uri name/qname-local name/qname name/to-qname name/uri-symbol |
| 11 | + node/element* node/element node/cdata node/xml-comment node/text-node |
| 12 | + node/extend-dom-as-data! node/element-node node/element-data) |
12 | 13 |
|
13 | 14 | (defn canonical-name |
14 | 15 | "Put (q)name into canonical form as per ns-env" |
15 | 16 | [n] |
16 | 17 | (name/canonical-name (qname-uri n) (qname-local n) "")) |
17 | 18 |
|
18 | | -;; TODO event-seq |
| 19 | +;;;; ## TODO event-seq |
| 20 | +;; This probably won't happen due to js' non-blocking semantics |
| 21 | +;; Instead, for clojurescript, the machinery around event-seq could be implemented |
| 22 | +;; as a transducer stack, such that a push-based source for parser events, like sax-js, |
| 23 | +;; could be used. |
| 24 | + |
19 | 25 | ;; TODO parse (use goog StringBuffer?) |
20 | 26 |
|
21 | 27 | (defn parse-str |
22 | 28 | "Use DOMParser to parse xml string" |
23 | 29 | ;; TODO detect browser specific parsererror tags |
24 | 30 | ;; see http://stackoverflow.com/questions/11563554/how-do-i-detect-xml-parsing-errors-when-using-javascripts-domparser-in-a-cross |
25 | | - [s & {:keys [content-type on-error] |
| 31 | + [s & {:keys [content-type on-error raw] |
26 | 32 | :or {content-type "text/xml" |
27 | 33 | on-error #(throw "XML parser error" {:doc % :input s})}}] |
28 | 34 | (let [dom (. (js/DOMParser.) |
29 | 35 | (parseFromString s content-type)) |
30 | 36 | doc (.-documentElement dom)] |
31 | | - (if (= "parsererror" (.-nodeName doc)) |
32 | | - (on-error doc) |
33 | | - doc))) |
| 37 | + (cond (= "parsererror" (.-nodeName doc)) |
| 38 | + (on-error doc) |
| 39 | + raw doc |
| 40 | + :else (element-data doc)))) |
34 | 41 |
|
35 | 42 | ;; TODO emit (use goog StringBuffer?) |
36 | 43 |
|
|
39 | 46 | [e & {:keys []}] |
40 | 47 | (. (js/XMLSerializer.) |
41 | 48 | (serializeToString |
42 | | - (node/coerce-to-dom e)))) |
43 | | - |
44 | | -(defn extend-nodes-as-qname! [] |
45 | | - (extend-protocol AsQName |
46 | | - js/Element |
47 | | - (qname-local [e] (.-localName e)) |
48 | | - (qname-uri [e] (.-namespaceURI e)) |
49 | | - js/Attr |
50 | | - (qname-local [e] (.-localName e)) |
51 | | - (qname-uri [e] (.-namespaceURI e)))) |
52 | | - |
53 | | -(defn- as-node [n] |
54 | | - (if (instance? js/Text n) |
55 | | - (.-wholeText n) ;; .-data |
56 | | - n)) |
57 | | - |
58 | | -(defn extend-dom-as-data! [] |
59 | | - (extend-type js/Element |
60 | | - ILookup |
61 | | - (-lookup [el k] |
62 | | - (case k |
63 | | - :tag (name/canonical-name (.-namespaceURI el) |
64 | | - (.-localName el) |
65 | | - "") |
66 | | - :attrs (.-attributes el) |
67 | | - :content (.-childNodes el) |
68 | | - (throw "XML tag has no key" {:key k :el el})))) |
69 | | - (extend-type js/NamedNodeMap |
70 | | - ILookup |
71 | | - (-lookup |
72 | | - ([attrs attr] |
73 | | - (if-let [i (.getNamedItemNS attrs (qname-uri attr) (qname-local attr))] |
74 | | - (.-value i) |
75 | | - nil)) |
76 | | - ([attrs attr not-found] |
77 | | - (if-let [i (.getNamedItemNS attrs (qname-uri attr) (qname-local attr))] |
78 | | - (.-value i) |
79 | | - not-found)))) |
80 | | - (extend-type js/NodeList |
81 | | - ISeqable |
82 | | - (-seq [nl] (map as-node (array-seq nl))) |
83 | | - ISequential |
84 | | - ICounted |
85 | | - (-count [nl] (.-length nl)) |
86 | | - IIndexed |
87 | | - (-nth |
88 | | - ([nl n] |
89 | | - (as-node (aget nl n))) |
90 | | - ([nl n nf] |
91 | | - (if (and (<= 0 n) (< n (.-length nl))) |
92 | | - (as-node (aget nl n)) |
93 | | - nf))))) |
94 | | - |
95 | | -(comment |
96 | | - |
97 | | - (extend-dom-as-data!) |
98 | | - (extend-nodes-as-qname!) |
| 49 | + (node/element-node e)))) |
99 | 50 |
|
100 | | - (let [{tag :tag {a1 "{DAV:}a1" a2 "a2" :as attrs} :attrs [c1 c2 c3] :content} |
101 | | - (parse-str "<xml xmlns:d=\"DAV:\" d:a1=\"dav-a1\" a2=\"normal a2\"> |
102 | | -Fancy Content <br/> More |
103 | | -</xml>")] |
104 | | - [tag a1 a2 c1 c2 c3]) |
105 | | - |
106 | | - ) |
0 commit comments