I'm trying to use Saxy to convert a streaming XML resource into e SAX event-stream. I'm having a hard time though with closing the document. I wonder if Saxy could help out here.
stream = ["<root>", "<elem>", "text", "</elem>", "</root>"]
{:ok, partial} = Saxy.Partial.new(MyEventHandler, [])
Stream.transform(stream, partial, fn xml_chunk, partial ->
case Saxy.Partial.parse(partial, xml_chunk) do
{:cont, partial} ->
# emit events
{Enum.reverse(partial.state.user_data), reset_user_data(partial)}
end
end)
|> Enum.to_list()
# returns something like
[:start_document, :start_element, :start_element, :characters, :end_element,
:end_element]
As you can see the last emitted event is :end_element (and not :end_document). The stream stops after "</root>", so parsing stops.
My questions:
- Should Saxy detect the end of the document here?
- In which situations would
Saxy.Partial.parse return a {:halt, _} response?
For now, my alternative solution would be to detect if the stack is empty, and terminate the stream based on that.
Stream.transform(stream, partial, fn
_, nil ->
# parsing has been stopped, halt the stream
{:halt, []}
xml_chunk, partial ->
case Saxy.Partial.parse(partial, xml_chunk) do
{:cont, %{state: %{stack: []}} = partial} ->
# the stack is empty, so we're done parsing the document: terminate the partial
{:ok, end_document} = Saxy.Partial.terminate(partial)
{Enum.reverse(end_document), nil}
{:cont, partial} ->
{Enum.reverse(partial.state.user_state), reset_user_state(partial)}
{:error, error} ->
raise error
end
end)
I'm trying to use
Saxyto convert a streaming XML resource into e SAX event-stream. I'm having a hard time though with closing the document. I wonder ifSaxycould help out here.As you can see the last emitted event is
:end_element(and not:end_document). The stream stops after"</root>", so parsing stops.My questions:
Saxy.Partial.parsereturn a{:halt, _}response?For now, my alternative solution would be to detect if the stack is empty, and terminate the stream based on that.