ducharmemp

ducharmemp

Saxaboom - a port of SaxMachine from Ruby for mapping XML to elixir data types

Hi all!

I’m still fairly new to elixir (mostly Ruby/C#/Rust in my background) and this is my first stab at a semi-useful library so feedback would be much appreciated!

I created a declarative library for creating data mappers that consume XML via strings or streams and return well-defined elixir structs, optionally with default values, attribute extraction, text extraction, and type casting. It’s also fairly fast at what it does based on my benchmarks on some large-ish XML documents. If you’ve used SaxMachine with Ruby it’s almost a 1:1 port to see if I could define a similar interface, since I really like the semantics of the SaxMachine DSL. The general gist is that you describe your expected structure and the library extracts out that information for you without having to specify XPaths or write Sax handlers yourself. This library also tries to be compatible with 3 (currently) XML parsers that support SAX-- erlsom, xmerl_sax_parser, and saxy.

Repo: GitHub - ducharmemp/saxaboom
Hex: saxaboom | Hex

Example:

You can turn:

<?xml version="1.0"?>
<catalog>
   <book id="bk101">
      <author>Gambardella, Matthew</author>
      <title>XML Developer's Guide</title>
      <genre>Computer</genre>
      <price>44.95</price>
      <publish_date>2000-10-01</publish_date>
      <description>An in-depth look at creating applications
      with XML.</description>
   </book>
</catalog>

Into:

{:ok,
 %Catalog{
   books: [
     %Book{
       id: "bk101",
       author: "Gambardella, Matthew",
       title: "XML Developer's Guide",
       genre: "Computer",
       price: 44.95,
       publish_date: {:ok, ~D[2000-10-01]},
       description: "An in-depth look at creating applications\n      with XML."
     }
   ]
 }}

with the following Saxaboom definition:

defmodule Book do
  use Saxaboom.Mapper

  document do
    element :book, as: :id, value: :id
    element :author
    element :title
    element :genre
    element :price, cast: :float
    element :publish_date, cast: &__MODULE__.parse_date/1
    element :description
  end

  def parse_date(value), do: Date.from_iso8601(value)
end


defmodule Catalog do
  use Saxaboom.Mapper

  document do
    elements :book, as: :books, into: %Book{}
  end
end

Most Liked

cblavier

cblavier

I don’t know anything about your use case, I’m just stopping by to say I love your project name :saxophone: :heart_eyes:

Good luck with your project!

ducharmemp

ducharmemp

Appreciate it very much! I updated the description because on reflection I did realize that I was a bit lacking on the “what the heck does this do” part of the library. Hopefully my examples clear it up for folks!

re: the name, I’m actually blown away that I was able to grab it :saxophone:

Adzz

Adzz

Nice, I made a very similar thing before too:

Always interesting to see how others approach the same problem

dimitarvp

dimitarvp

I love it how your latest commit message is just sure. :003:

ducharmemp

ducharmemp

Definitely very similar, nice looking library! I actually read through your blog post on App signal, I think? I think that saxaboom can fill a specific niche that you called out in there, where you don’t want to hold the whole dom/document in memory at once. Technically speaking Saxaboom does single shot parsing with support for streams, with no ability to access contextual information (as in, no ability to query siblings) so whatever doesn’t match up against a parae can be easily thrown away.

That said, the more libs the merrier I think, I’ll have to read through the data schema code because I definitely agree with respect to the overall similarities! Plus it was a fun lib to tinker with :grinning:

Where Next?

Popular in Libraries Top

marcuslankenau
I feel kind of stuck with the absence of a proper xml library for Elixir. Currently I use SweetXML which was ok for me more or less to pa...
New
kelvinst
Hey everyone! Well, we made this lib a while ago and now we decided to finally go out and public with it! It’s a tool for creating and m...
New
michalmuskala
Hello everybody. I have just released Jason - a new JSON library. You might be wondering, why do we need a new library? The primary foc...
New
wfgilman
I’ve cleaned up and open sourced three financial libraries I was using for my company. They are bindings for the APIs of these three comp...
New
Crowdhailer
I have been updating a library that allows you to pipe between functions that use the erlang result tuple convention. Assuming you have...
New
benlime
LiveMotion enables high performance animations declared on the server and run on the client. As a follow up to my previous thread A libr...
New
Jskalc
Hi! Today, after a couple weeks of development I’ve released v0.1 of LiveVue. It’s a seamless integration of Vue and Phoenix LiveView, i...
New
bryanjos
Hi, I just published version 0.23.0 of Elixirscript. Most of the changes are around JavaScript interop now that Elixirscript uses the ...
New
vic
Expat is a tiny experiment I did for extracting patterns and being able to reuse them (compose and share patterns between elixir librarie...
New
mischov
import Meeseeks.CSS html = HTTPoison.get!("https://news.ycombinator.com/").body for story &lt;- Meeseeks.all(html, css("tr.athing")) do...
New

Other popular topics Top

bsollish-terakeet
Credo is smart enough to check for (something like) this: assert length(the_list) == 0 with this response: Checking if an enum is empt...
New
sergio_101
I am VERY much an elixir newbie. I have taken one elixir course and one phoenix course on Udemy. During that course, I saw the instructor...
New
grych
Hi folks, Few months ago I have announced the proof-of-concept of the library to manipulate the browsers DOM objects directly from Elixi...
639 49522 488
New
Jim
As a follow up to my earlier question: I have the code compiling and running but not getting a successful login from the rest server. ...
New
freewebwithme
Using vs code and installed ElixirLS: support and debugger. And I got an error popped up on start up says Failed to run ‘elixir’ comma...
New
minhajuddin
I have seen a lot of code which picks the first element from a list using Enum.at(0) instead of List.first. Is there a reason why people ...
New
ashish173
I am using Ecto timestamps with postgres, I can see the timestamps() use the :naive_dateime but for my use case I wanted to store the ti...
New
vonH
When I run the Plug and I recompile I wind up having to use Ctrl C to quit iex and start again. Witht the help of rlwrap I can use the cu...
New
stefanluptak
Hello everybody, usually, I use a 29" ultra-wide monitor for VSCode which can easily accomodate explorer (files panel) + file with code ...
New
lanycrost
Hi everyone! I need implement if…else if…else condition from my elixir code, and anymore of this control flow structures not work proper...
New

Sub Categories:

We're in Beta

About us Mission Statement