Copyright | (c) Getty Ritter 2017 |
---|---|
License | BSD |
Maintainer | Getty Ritter <xleb@infinitenegativeutility.com> |
Stability | experimental |
Safe Haskell | None |
Language | Haskell2010 |
- type Xleb a = XlebT Identity a
- runXleb :: String -> Xleb t -> Either XlebError t
- data XlebT m a
- runXlebT :: Monad m => String -> XlebT m t -> m (Either XlebError t)
- data XlebError
- errorString :: XlebError -> String
- elem :: Monad m => String -> XlebT m t -> XlebT m t
- attr :: Monad m => String -> Parse t -> XlebT m t
- contents :: Monad m => Parse t -> XlebT m t
- rawElement :: Monad m => XlebT m Element
- child :: Monad m => Selector -> XlebT m t -> XlebT m t
- children :: Monad m => Selector -> XlebT m t -> XlebT m [t]
- type Parse t = String -> Either String t
- string :: Parse String
- number :: (Read n, Num n) => Parse n
- reader :: Read a => Parse a
- data Selector
- byTag :: String -> Selector
- any :: Selector
How To Use Xleb
The Xleb
monad describes both parsing and traversing a given XML
structure: several of the functions to produce Xleb
computations
take other Xleb
computations, which are run on various sub-parts of
the XML tree. Consequently, instead of decomposing an XML structure
and passing it around to various functions, the Xleb
language treats
"the current location in the tree" as an implicit piece of data in the
Xleb
monad.
You will generally want to identify your root note with the elem
function to ensure that your root note has the tag you
expect. Children of that node can be accessed using the child
or
children
function to either unambiguously find a specific child
element, or to find all child elements that match a given selector and
apply a Xleb
computation to each of them.
a <- X.child (X.byTag "a") parseA b <- X.children (X.byTag "b") parseB
Leaf data tends to come in two forms in XML: attribute values (like
<tag attr="value">
) or tag content (like
<tag>value</tag>
). In both cases, the Xleb
functions allow
you to parse that content however you'd like by providing an arbitrary
function of type
. The "xleb" library
provides several built-in functions of this type for common
situations.String
-> Either
String
a
c <- X.attr "index" X.number d <- X.contents X.string
Finally, the Xleb
monad has Alternative
instances which allow for
concise expression of optional values or multiple possibilities.
e <- X.children X.any (parseA <|> parseB) f <- optional (X.attr "total" X.number)
Consequently, for an XML structure like the following:
<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>
We can write a Xleb
computation which is capable of parsing this
structure in a handful of lines:
import Control.Applicative (optional) import qualified Text.XML.Xleb as X feed :: X.Xleb (String, Maybe String, [(String, String)]) 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 (feedTitle, feedAuthor, feedEntries) entry :: X.Xleb (String, String) entry = (,) <$> X.attr "title" X.string <*> X.contents X.string
The Xleb
monad
type Xleb a = XlebT Identity a Source #
The Xleb
monad describes a computation used to parse a fragment
of XML from a particular element of an XML structure. This may fail
with an error, or it may produce a value.
The XlebT
monad transformer
The XlebT
monad transformer describes a computation used to
parse a fragment of XML from a particular element of an XML
structure. This may fail with an error, or it may produce a value.
Errors
The XlebError
type describes the various errors that can occur
in the course of parsing an XML structure. If you simply want the
human-readable string that corresponds to your error, then use the
errorString
function.
XEInElem String XlebError | Describes the element context in which an error occurred |
XEInAttr String XlebError | Describes the attribute context in which an error occurred |
XEParseFailure String | Some parser function was unable to produce a value from the string embedded in an XML element |
XENoSuchAttribute String | A |
XEUnexpectedElement String String | A |
XENoMatchingElement Selector | A |
XEAmbiguousElement Selector | A |
XEBadXML | The "xml" library was unable to parse the document as XML. |
XOtherError String | Another error occurred which was not described by the above constructors |
errorString :: XlebError -> String Source #
Convert a XlebError
value to the corresponding human-readable
string.
Element Structure
elem :: Monad m => String -> XlebT m t -> XlebT m t Source #
will ensure that the currently focused element is a
tag named elem
n tn
and will then evaluate it using the computation
t
. This will fail with XEUnexpectedElement
if the tag is named
something else.
attr :: Monad m => String -> Parse t -> XlebT m t Source #
Find an attribute on the current focus element and parse it to a
value of type t
. If the parse function fails, then this will fail
with XEParseFailure
.
contents :: Monad m => Parse t -> XlebT m t Source #
Take the string content of the current element and parse it to a
value of type t
. If the parse function fails, then this will fail
with XEParseFailure
.
rawElement :: Monad m => XlebT m Element Source #
Access the raw underlying XML element that we are processing. This is sometimes necessary for working with free-form XML data.
child :: Monad m => Selector -> XlebT m t -> XlebT m t Source #
Use a Selector
that unambiguously identifies a single child
element of the current element and then parse it according to a
given XlebT
computation focused on that element. If no child
matches the provided Selector
, then this will fail with
XENoMatchingElement
. If multiple children match the provided
Selector
, then this will fail with XEAmbiguousElement
.
children :: Monad m => Selector -> XlebT m t -> XlebT m [t] Source #
Use a Selector
that identifies some child elements of the
current element and parse each according to a given XlebT
computation, which will be repeated with focus on each child
element, and returning the resulting values as a list. If no child
elements match the Selector
, then this will return an empty list.
Parsing contained string data
type Parse t = String -> Either String t Source #
A value of type
is a function that can either produce
a value of type Parse
tt
or fail with a string message.
string :: Parse String Source #
A Parse
function that accepts arbitrary string input without
failing.
Selecting Elements
A Selector
represents some criteria by which child elements are
matched.