Skip to content

Instantly share code, notes, and snippets.

@JoeZ99
Last active May 8, 2022 23:29
Show Gist options
  • Save JoeZ99/eab68cb5d90fc8a99023e252ab6ebcc9 to your computer and use it in GitHub Desktop.
Save JoeZ99/eab68cb5d90fc8a99023e252ab6ebcc9 to your computer and use it in GitHub Desktop.
Use sax to make stream output out of parsing xml files
defmodule XmlStreamer do
defp to_elements_stream(xml_stream) do
{:ok, partial} = Saxy.Partial.new(XmlEventHandler)
Stream.chunk_while(xml_stream, partial, &maybe_items/2, &finalize/1)
end
defp maybe_items(chunk, partial) do
with {:cont, partial} <- Saxy.Partial.parse(partial, chunk),
{:ok, partial, items} <- fetch_items(partial) do
if items == [], do: {:cont, partial}, else: {:cont, items, partial}
else
{:error, exception} when is_exception(exception) ->
raise Saxy.ParseError.message(exception)
{:error, reason} ->
raise reason
_ ->
raise "Xml parsing error"
end
end
defp finalize(partial) do
case Saxy.Partial.terminate(partial) do
{:ok, %{items: []}} ->
{:cont, %{}}
{:ok, %{items: items}} ->
{:cont, items, %{}}
{:error, exception} when is_exception(exception) ->
raise Saxy.ParseError.message(exception)
end
end
defp fetch_items(%{state: %{user_state: %{items: items} = user_state} = state} = partial) do
partial = %{partial | state: %{state | user_state: %{user_state | items: []}}}
{:ok, partial, items}
end
defp fetch_items(_), do: {:error, "Something wrong when processing sax events"}
end
@JoeZ99
Copy link
Author

JoeZ99 commented May 8, 2022

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment