infinite negative utility

xleb

The xleb library is a DSL for declaratively parsing XML structures. It uses a monadic structure to implicitly traverse the underlying XML structure, match on parts, and extract the relevant data.

Consider an XML format that looks like the following, with the author tags being considered optional:

<feed>
  <title>Feed Name</title>
  <author>Pierre Menard</author>
  <entry title="Entry 01">First Post</entry>
  <entry title="Entry 02">Second Post Post</entry>
</feed>

A parser for this format using the xleb library might look like this:

import           Control.Applicative (optional)
import qualified Text.XML.Xleb as X

data Feed = Feed
  { feedTitle :: String
  , feedAuthor :: Maybe String
  , feedEntry :: [Entry]
  } deriving (Eq, Show)

data Entry = Entry
  { entryTitle :: String
  , entryContents :: String
  } deriving (Eq, Show)

feed :: X.Xleb Feed
feed = X.elem "feed" $ do
  feedTitle <- X.child (X.byTag "title") $ X.contents X.string
  feedAuthor <- optional $ X.child (X.byTag "author") $ X.contents X.string
  feedEntries <- X.children (X.byTag "entry") entry
  return Feed { .. }

entry :: X.Xleb Entry
entry = Entry <$> X.attr "title" X.string <*> X.contents X.string