-
Notifications
You must be signed in to change notification settings - Fork 93
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Support for XML transformations #137
Comments
You could use spec-tools for the XML->EDN transformation but I think you still need an XML->EDN->XML converter. Last time we needed this ended up writing a small utility lib for this. <products><product><id>1</id></product><product><id>2</id></product></products> would be converted into something like this: {:products [{:id 1} {:id 2}]} ... and back. works nicely for a large subset of XML. The EDN format could have spec and spec-tools could encode & decode the types. PS. oh, one version of the xml-helper is here. Would need some love, last commit 4years ago and haven't most likely used since :O |
Hi there, Thanks! I tried the xml-helper link (noxml) but I got a 404..? Also, re: "I think you still need an XML->EDN->XML converter", could you expand on that? I was hoping/assuming that spec-tools could provide all of XML(A)->EDN(A) With an understanding that some extra work would be required for the XML transformations? |
spec-tools is not an XML-parser. The default XML-parsers return the XML in the verbose map format with The linked lib seems internal, not fully tested. Here's a full round-robin with JSON. The JSON->EDN is done by Muuntaja: (require '[clojure.spec.alpha :as s])
(require '[spec-tools.core :as st])
(require '[muuntaja.core :as m])
(s/def ::name string?)
(s/def ::birthdate inst?)
(s/def ::age int?)
(s/def ::languages
(s/coll-of
(s/and keyword? #{:clj :cljs})
:into #{}))
(s/def ::user
(s/keys
:req-un [::name ::languages ::age]
:opt-un [::birthdate]))
(defn encode-json [x] (slurp (m/encode m/instance "application/json" x)))
(defn decode-json [x] (m/decode m/instance "application/json" x))
(def ilona {:birthdate #inst "1968-01-02T15:04:05Z"
:age 48
:name "Ilona"
:languages #{:clj :cljs}})
(as-> ilona $
(doto $ prn)
(encode-json $)
(doto $ prn)
(decode-json $)
(doto $ prn)
(st/decode ::user $ st/json-transformer)
(do (assert (= $ ilona)) $)
(doto $ prn)
(encode-json $)
(doto $ prn)
(assert (= (encode-json ilona) $)))
; {:birthdate #inst "1968-01-02T15:04:05.000-00:00", :age 48, :name "Ilona", :languages #{:clj :cljs}}
; "{\"birthdate\":\"1968-01-02T15:04:05Z\",\"age\":48,\"name\":\"Ilona\",\"languages\":[\"clj\",\"cljs\"]}"
; {:birthdate "1968-01-02T15:04:05Z", :age 48, :name "Ilona", :languages ["clj" "cljs"]}
; {:birthdate #inst "1968-01-02T15:04:05.000-00:00", :age 48, :name "Ilona", :languages #{:clj :cljs}}
; "{\"birthdate\":\"1968-01-02T15:04:05Z\",\"age\":48,\"name\":\"Ilona\",\"languages\":[\"clj\",\"cljs\"]}" |
Hi there, Thanks for the advice! I've been experimenting with transforming the verbose So, I have a data spec like this:
And an "xml transformer" like this:
Then I can use the following code:
To transform
Into
So, my However, I then wanted to define a spec
So if there are many functions making up the decoding, for which it would be nice to have a spec I tried defining
Which works ok of course when The only other idea I thought about to avoid manually creating the extra So, in conclusion I'm unsure about how to proceed (apart from manually creating the |
Just following this up, I found a solution to my problem.. I decided to define the
Then I can use the following code:
To transform
Into
As in, spec-tools is doing the coercion of
|
Hi there,
I have a small project to transform one xml format into another (call them fmt-a and fmt-b). I thought Clojure Spec might be useful to define the shape of the data at each stage of the transformation and check the transformation works correctly for expected inputs.
Then I found spec-tools and it's transformers in this blog post:
https://www.metosin.fi/blog/spec-transformers/
So I thought I'd investigate that. I noted that although it supports JSON it doesn't seem to support XML yet (although XML is mentioned in the blog post?)
Anyway this was going to be my approach with spec-tools:
{:tag :attributes :content structure}
) to fmt-a (i.e.{:fmt-a-key some-val}
){:fmt-b-key some-val}
){:tag :attributes :content structure}
)Does this sound sensible? I'm not sure how to achieve all of the above with spec-tools, but I was going to start experimenting with step 3, the core data transformation.
One issue I can see before I proceed, is that "invalid" inputs would raise an error at step 2 or 3, so the errors wouldn't make a lot of sense in relation to the xml input file.
Note: there's no xml schema available for fmt-a or fmt-b, if that matters.
Thanks!
The text was updated successfully, but these errors were encountered: