Skip to content

Instantly share code, notes, and snippets.

@sasa1977
Created July 30, 2013 14:27
Show Gist options
  • Save sasa1977/6113377 to your computer and use it in GitHub Desktop.
Save sasa1977/6113377 to your computer and use it in GitHub Desktop.
defrecord Person, id: nil, name: nil
defrecord ParserState, persons: [], current_person: nil
defmodule TestXmerlSax do
def xml do
%b(
<doc>
<person id="1">Joe Armstrong</person>
<person id="2">José Valim</person>
</doc>
)
end
def run do
IO.inspect :xmerl_sax_parser.stream("",
continuation_state: xml,
continuation_fun: function(:get_rest, 1),
event_fun: function(:event_fun, 3),
event_state: ParserState.new
)
end
defp get_rest("") do
{"", :undefined}
end
defp get_rest(buffer) do
String.next_grapheme(buffer)
end
defp event_fun({:startElement, _, 'person', _, attributes}, _, state) do
Person.new(id: id(attributes))
|> state.current_person
end
defp event_fun({:characters, chars}, _, ParserState[current_person: person] = state) when person != nil do
person.name(:unicode.characters_to_binary(chars))
|> state.current_person
end
defp event_fun({:endElement, _, 'person', _}, _, ParserState[current_person: person] = state) do
state.
update_persons([person | &1]).
current_person(nil)
end
defp event_fun(_event, _location, state) do
state
end
defp id(attributes) do
Enum.find_value(attributes, function do
({_, _, 'id', id}) -> list_to_integer(id)
_ -> nil
end)
end
end
TestXmerlSax.run
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment