xml-conduit-decode- Historical cursors & decoding on top of xml-conduit.

Copyright(c) Ben Kolera
MaintainerBen Kolera
Safe HaskellNone



These functions allow you to pull haskell values out of a HCursor.

The idea is that you use the HCursor combinators to get where you need to in the XML, and something in this file allows you to parse the XML into values.

Because of how the underlaying Text.XML.Cursors work, these functions have the following oddities:

  • The cursor could actually be at 0 or many elements, so the decodeMay, decodeSingle,decodeMany,decodeNel functions allow you to express how many elements you want to decode. DecodeCursor powers these functions.
  • The cursor has no concept of being at an attribute, so we need the hack of decodeAttrMay,decodeAttr to pull out a named attribute from the positions that the cursor is in.
  • Choices are weird and our only spot where we have multiple different elements at a Cursor and need to disambiguate them by the element name. DecodeChoice pairs element names with a decoder that will decode the element into a sum type constructor. See the decodeChoice function and the choice constructor.



type DecodeResult a = Either (Text, CursorHistory) a Source #

Gives you a the result of the decoding or a text description of the error and a history of cursor movements prior to the error.

class DecodeCursor a where Source #

DecodeCursor is the crux of pulling things out of XML in a reusable way. You'll want to implement it for any data type that you wish to construct out of a XML element.

Minimal complete definition



decode :: HCursor -> DecodeResult a Source #

You wont call this outside of here. Call decodeSingle instead

decode :: DecodeCursor a => HCursor -> DecodeResult a Source #

You wont call this outside of here. Call decodeSingle instead

decodeMay :: DecodeCursor a => HCursor -> DecodeResult (Maybe a) Source #

Decodes zero or one results from the cursor.

decodeSingle :: DecodeCursor a => HCursor -> DecodeResult a Source #

Decodes a single result from the Cursor. Errors if the cursor is empty.

decodeDefault :: DecodeCursor a => a -> HCursor -> DecodeResult a Source #

Decodes a result from the cursor, or provides the default if the cursor is empty.

decodeMany :: DecodeCursor a => HCursor -> DecodeResult [a] Source #

Decodes 0 or more results from the cursor.

decodeNel :: DecodeCursor a => HCursor -> DecodeResult (NonEmpty a) Source #

Decodes 1 or more results. Fails if the cursor is empty.

decodeDocument :: DecodeCursor a => (HCursor -> HCursor) -> Document -> Either (Text, CursorHistory, Document) a Source #

Takes an entire document, an a cursor shift to shift from the top of the document to where you need to start parsing.

decodeAttr Source #


:: Text

The attribute name

-> (Text -> Either Text a)

A parser from Text to either an error or the result

-> HCursor

The cursor to parse from

-> DecodeResult a 

Grab an attribute from the element focused by the cursor

data ChoiceDecoder a Source #

Describes how to navigate to the choice element and then decode it.

choice Source #


:: Shift

Given a shift to the element (e.g. laxElement "foo")

-> (HCursor -> DecodeResult a)

And a parser

-> ChoiceDecoder a 

Constructs a ChoiceDecoder

decodeChoice :: [ChoiceDecoder a] -> HCursor -> DecodeResult a Source #

Given a choice of elements, decode the first where the shift succeeds.

Using it usually takes this shape:

  instance DecodeCursor LibrarySection where
    decode = decodeChoice
      [ choice (laxElement "fiction") decodeFiction
      , choice (laxElement "non_fiction") decodeNonFiction
        decodeFiction  c   = Fiction $ parseCursor parseText c
        decodeNonFiction c = NonFiction $ parseCursor parseDouble c

decodeAttrMay :: Text -> (Text -> Either Text a) -> HCursor -> DecodeResult (Maybe a) Source #

Optionally grab an attribute from the cursor.

parseCursor :: (Text -> Either Text a) -> HCursor -> DecodeResult a Source #

Helper function for parsing the text of the cursor

cursorContents Source #


:: HCursor

The cursor to extract all text nodes from

-> CursorResult Text

Left if the cursor was failed, else all text nodes concatenated into a single text

Grabs the concatenated text of all elements of a cursor.