1

I am a Clojure n00b trying to create some XML strings.

My goal is to create something like this:

<?xml version="1.0" encoding="UTF-8"?>
<items>
  <item name="n0">n0 value</item>
  <item name="n1">n1 value</item>
  <item name="n2">n2 value</item>
</items>

I can use the clojure.data.xml library's element function directly like this:

(element :items {} 
  (element :item {:name "n0"} "n0 value")
  (element :item {:name "n1"} "n1 value")
  (element :item {:name "n2"} "n2 value"))

and this responds to emit-str as expected and prints the xml I am after.

The problem I am having is that I have a variable number of items for a given items collection, so I want to do something that looks like this:

(def collection-of-items 
    [(element :item {:name "n0"} "n0 value") 
     (element :item {:name "n1"} "n1 value")])

(element :items {} 
  collection-of-items)

I.e., I make a collection of several xml element objects, and give that as the :content argument for the ':items' element definition.

These two forms evaluate correctly, but then emit-str fails when invoked on the result of the element invocation.

So my question is: How do I pass the 'collection-of-items' var to the element function as an argument so it will appear as a simple variable argument list? Or am I Missing the Clojure Boat completely here?

Thanks all!

1 Answer 1

4

Use apply:

user=> (def collection-of-items 
    [(element :item {:name "n0"} "n0 value") 
     (element :item {:name "n1"} "n1 value")])
#'user/collection-of-items
user=> (def b (apply element :items {} collection-of-items))
#'user/b
user=> b
#clojure.data.xml.Element{:tag :items, :attrs {}, :content (#clojure.data.xml.Element{:tag :item, :attrs {:name "n0"}, :content ("n0 value")} #clojure.data.xml.Element{:tag :item, :attrs {:name "n1"}, :content ("n1 value")})}
user=> (emit-str b)
"<?xml version=\"1.0\" encoding=\"UTF-8\"?><items><item name=\"n0\">n0 value</item><item name=\"n1\">n1 value</item></items>"
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.