silverdr
PostgreSQL XML data and Elixir / Ecto?
Any well established methods of handling XML data from / to PostgreSQL xml columns using Ecto? How do Elixir veterans do it? If they do, of course… ![]()
Most Liked
silverdr
Roger, thank you. I’ll have to sculpt something out of it. I didn’t say it’s not possible but that nothing I found is “full-fledged” as in “handles all both ways”. Things are scattered, and there are bits and pieces here and there. Even with your suggestions – where you surely have done these type of things before – it’s still three different libs, including an Erlang one. I’d dream of something like e. g. JSON.decode, JSON.encode, as XML.de/encode, augmented with XML.validate and XML Ecto type. Anyway - it is what it is.
Hehe… Yes, I know. Been there, seen that. Not in Elixir though ![]()
dimitarvp
I am joining @christhekeele here – f.ex. using :xmerl is maddening because it has a nice low-level streaming interface (among others!) because on the one hand, 95% of the code is exactly the same… but the other 5% vary every frakkin time. This really makes it very difficult to extract out libraries. I entertained the idea but ultimately concluded it would add too little value for what would basically be just one instance of a SAX parser with the ability to pass “callbacks” to it… something everyone can roll in literal one hour maximum.
dimitarvp
As the efficiency maniac that I will always be, I’d use Erlang’s :xmerl even if I know no XML content would ever be more than 20KB.
But I am not aware of a library that directly adds a custom Ecto.Type for it, no.
christhekeele
Although even on parsers/builders (especially the latter) choice seems to be limited.
I’m don’t know how expansive the choice needs to be, really—parsing and building are pretty straightforward until you need SAX, and even then you just use a SAX parser if you’re memory constrained. I’ve built a few XML-handling things in Elixir just fine with sweet_xml and xml_builder. Usually end up with something like this as my main entrypoint, with application-specific helpers for common workflows, and submodules for specific domains (ex XML.SOAP).
XML module
defmodule XML do
defmacro __using__(_options \\ []) do
quote do
import XML, only: [sigil_x: 1, sigil_x: 2]
end
end
@type document() :: SweetXml.doc()
@type element() :: SweetXml.xmlElement()
####
# XML builder functions
##
defdelegate document(elements), to: XmlBuilder
defdelegate document(name, attrs_or_content), to: XmlBuilder
defdelegate document(name, attrs, content), to: XmlBuilder
defdelegate element(name), to: XmlBuilder
defdelegate element(name, attrs), to: XmlBuilder
defdelegate element(name, attrs, content), to: XmlBuilder
####
# XML parser functions
##
defdelegate generate(any, options \\ []), to: XmlBuilder
defdelegate parse(document, options \\ []), to: SweetXml
defdelegate sigil_x(path, modifiers \\ []), to: SweetXml
defdelegate xpath(parent, spec, subspec \\ []), to: SweetXml
end
I guess the option is to somehow treat the column as text and then do some string parsing, etc.
That really depends on what you’re doing with the XML. If you’re looking for feedback, share some details about the problem you’re trying to solve with us!
silverdr
In short the case at hand is:
- I receive XML document in an xml DB column
- I need to retrieve it and validate it against XSD schema
- IF it is valid given the schema then
- decompose (parse) it into Elixir terms
- process some data from the parsed document
- build a response XML document with results of the processing, preferably validate it also
- store the response document to xml column in the database
- IF it is not valid then I need only to construct error response XML doc and store it as above.
The columns are of xml type and I cannot change it. I can imagine reading and processing / parsing out data from strings. I can also imagine “shelling out” to xmllint or something to do the validations, etc. But it would be “nice to have” it all in some Elixir lib or so.
P. S. No, it is not SOAP I am doing there ![]()







