Share your thoughts in the 2024 State of Clojure Survey!

Welcome! Please see the About page for a little more info on how this works.

+1 vote
in data.xml by

I’m using clojure.data.xml 0.2.0-alpha6 to merge two SVG documents into a new document.

As part of that, I’m creating a few new elements.

I think I’m using the namespace as intended, as per the c.d.xml README; for example:

(alias-uri 'svg "http://www.w3.org/2000/svg")
(element ::svg/svg {}
  (element ::svg/g {}
    (:content de)))

This is technically working just fine, but when I emit the new document (root elem) to a string
using emit-str (or indent-str), the namespace is assigned an alias and that alias is used for
all of the elements in the entire document; for example:

<a:svg xmlns:a="http://www.w3.org/2000/svg" version="1.1" viewBox="0 0 1748 1740">
  <a:g>...

The thing is, in this case, that alias isn’t necessary, as every element in the document is in the
same namespace, so it can be the default namespace. In other words, I’d prefer that the output look
like this:

<svg xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0 0 1748 1740">
  <g>...

Or, failing that, I’d like the alias to be svg rather than a, like this:

<svg:svg xmlns:svg="http://www.w3.org/2000/svg" version="1.1" viewBox="0 0 1748 1740">
  <svg:g>...

Does anyone know whether either of those scenarios are simple+easy to achieve with the current
versions of clojure.data.xml ?

I’ve tried explicitly adding the xmlns attribute to the root elem — this works with 0.0.8 but not with 0.2.0-alpha6; strange things happen.

I’m asking this question because:

  1. I’m curious
  2. If this isn’t currently possible with 0.2.0, I’d want to turn this into a feature request.

Thanks!

1 Answer

+2 votes
by
selected by
 
Best answer

I'm surprised that setting the xmlns attribute on the root element doesn't work - this should be sufficient. Do you have a reproducible case and the output you see?

I do something similar to all this (with 2.0.0-alpha5, which I don't think is meaningfully different than alpha6 for this) in the pom gen feature of tools.deps: https://github.com/clojure/tools.deps.alpha/blob/master/src/main/clojure/clojure/tools/deps/alpha/gen/pom.clj - in line 22 is the alias and line 70 is setting xmlns.

by
Thanks @alexmiller! That’s interesting — I didn’t think of both using the namespace as a… namespace in the element name keywords and _also_ adding the `xmlns` attribute explicitly. Based on my extensive experience with XML back-in-the-day, I figured that specifying the namespace on the elements would be the correct way to specify the namespace to the XML library (i.e. StAX) and that it would have its own API for how to express the namespace when converting the in-memory document model to an XML document string.

Not sure if that made sense, but I tried your approach with 0.2.0-alpha6 and it’s working for me. Thank you!
by
These things work together - the namespace is only needed in the elements if it differs from the default, so setting the default gets you to your desired goal. Both "mean" the same thing though semantically (but certainly the one without namespaces may be more what users expect).
by
Got it, thanks!

This might be worth adding to the README, BTW. Any interest in a patch?
by
If you want to drop an example here I can add it
...