Literal XML in Erlang with parse_transform/2

One of the things I dislike about Erlang is that it severely impairs bragging opportunities. Yesterday I wrote a module that allows writing literal XML in the source and have it parsed into Erlang structures at compile time—sort of like E4X minus the manipulation goodies at runtime (at least for now).

You write:


Doc = '<greeting>Hello!</greeting>',
io:format("~p~n", [Doc]).

And it prints…


{xmlElement,greeting,
            greeting,
            [],
            {xmlNamespace,[],[]},
            [],
            1,
            [],
            [{xmlText,[{greeting,1}],1,[],"Hello!",text}],
            [],
            "/tmp",
            undeclared}

In most languages I’m familiar with, this would have granted the author instant Yacc-demigod status. With Erlang… it was less than 40 LOC. Hardly something you’d wear at a party.

Anyway, this code owes everything to Philip’s writings. It also uses parse_transform/2, and “programmers are strongly advised not to engage in parse transformations and no support is offered for problems encountered”. So unless you, like me, are still at the kid-in-a-candy-shop stage of Erlang experience, think twice before using this in production, ok?

The code is here.

Share
  • Trackbacks are closed
  • Comments (4)
    • Luke Gorrie
    • June 27th, 2007

    Very very nice :-)

  1. Thanks for the mention!

    I really like the idea of using the structure of an atom to trigger a parse transformation – it keeps the original source code very clean.

    • Qrilka
    • June 26th, 2007

    And why do you have 3 times ‘greeting’ in Erlang and 1 time in XML (or 2 times if we include closing tag) and what is ”/tmp” and undeclared? It doesn’t seem clear to me.

  2. Perhaps it’s clearer with record information loaded in the console (io:format doesn’t show it):

    
    #xmlElement{name = greeting,
                expanded_name = greeting,
                nsinfo = [],
                namespace = #xmlNamespace{default = [],nodes = []},
                parents = [],
                pos = 1,
                attributes = [],
                content = [#xmlText{parents = [{greeting,1}],
                                    pos = 1,
                                    language = [],
                                    value = "Hello!",
                                    type = text}],
                language = [],
                xmlbase = "/tmp",
                elementdef = undeclared}
    
    
    
Comments are closed.