Skip to content

Closing the event stream - detect end_document #110

Description

@joeppeeters

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)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions