-- Hoogle documentation, generated by Haddock -- See Hoogle, http://www.haskell.org/hoogle/ -- | XML back and forth! Parser, renderer, ToXml, FromXml, fixpoints. -- -- XML back and forth! Parser, renderer, ToXml, FromXml, fixpoints. @package xmlbf @version 0.6.1 -- | XML back and forth! -- -- xmlbf provides high-level tools for encoding and decoding -- XML. -- -- xmlbf provides tools like dfpos and dfposM for -- finding a fixpoint of an XML fragment. -- -- xmlbf provides FromXml and ToXml typeclasses -- intended to be used as the familiar FromJSON and ToXml -- from the aeson package. -- -- xmlbf doesn't do any parsing of raw XML on its own. Instead, -- one should use xmlbf together with libraries like -- xmlbf-xeno or xmlbf-xmlhtml for this. module Xmlbf -- | Run a Parser on an XML fragment body. -- -- Notice that this function doesn't enforce that all input is consumed. -- If you want that behavior, then please use pEndOfInput in the -- given Parser. runParser :: Parser a -> [Node] -> Either String a -- | XML parser for a value of type a. -- -- You can build a Parser using pElement, -- pAnyElement, pName, pAttr, pAttrs, -- pChildren, pText, pEndOfInput, any of the -- Applicative, Alternative, Monad or related -- combinators. -- -- Run a Parser using runParser. data Parser a -- | pElement "foo" p runs a 'Parser p inside a -- Element node named "foo". This parser fails if -- such element does not exist at the current position. -- -- Leading whitespace is ignored. If you need to preserve that whitespace -- for some reason, capture it using pText before using -- pElement. -- -- Consumes the matched element from the parser state. pElement :: Text -> Parser a -> Parser a -- | pAnyElement p runs a Parser p inside -- the Element node at the current position, if any. Otherwise, if -- no such element exists, this parser fails. -- -- You can recover the name of the matched element using pName -- inside the given Parser. However, if you already know -- beforehand the name of the element that you want to match, it's better -- to use pElement rather than pAnyElement. -- -- Leading whitespace is ignored. If you need to preserve that whitespace -- for some reason, capture it using pText before using -- pAnyElement. -- -- Consumes the matched element from the parser state. pAnyElement :: Parser a -> Parser a -- | Returns the name of the currently selected Element. -- -- This parser fails if there's no currently selected -- Element (see pElement, pAnyElement). -- -- Doesn't modify the parser state. pName :: Parser Text -- | Return the value of the requested attribute, if defined. Returns an -- empty Text in case the attribute is defined but no value -- was given to it. -- -- This parser fails if there's no currently selected -- Element (see pElement, pAnyElement). -- -- Consumes the matched attribute from the parser state. pAttr :: Text -> Parser Text -- | Returns all of the available element attributes. -- -- Returns empty Text as values in case an attribute is -- defined but no value was given to it. -- -- This parser fails if there's no currently selected -- Element (see pElement, pAnyElement). -- -- Consumes all the attributes for this element from the parser -- state. pAttrs :: Parser (HashMap Text Text) -- | Returns all of the immediate children of the current element. -- -- If parsing top-level nodes rather than a particular element (that is, -- if pChildren is not being run inside pElement), -- then all of the top level Nodes will be returned. -- -- Consumes all the returned nodes from the parser state. pChildren :: Parser [Node] -- | Returns the contents of a Text node. -- -- Surrounidng whitespace is not removed, as it is considered to be part -- of the text node. -- -- If there is no text node at the current position, then this parser -- fails. This implies that pText never returns an -- empty Text, since there is no such thing as a text node without -- text. -- -- Please note that consecutive text nodes are always concatenated and -- returned together. -- --
-- runParser pText (text "Ha" <> text "sk" <> text "ell") -- == Right (text "Haskell") ---- -- Consumes the text from the parser state. This implies that if -- you perform two consecutive pText calls, the second will always -- fail. -- --
-- runParser (pText >> pText) (text "Ha" <> text "sk" <> text "ell") -- == Left "Missing text node" --pText :: Parser Text -- | Succeeds if all of the elements, attributes and text nodes have been -- consumed. pEndOfInput :: Parser () -- | Encodes a list of XML Nodes, representing an XML fragment body, -- to an UTF8-encoded and XML-escaped bytestring. -- -- This function doesn't render self-closing elements. Instead, all -- elements have a corresponding closing tag. -- -- Also, it doesn't render CDATA sections. Instead, all text is escaped -- as necessary. encode :: [Node] -> Builder -- | Either a text or an element node in an XML fragment body. -- -- Construct with text or element. Destruct with -- Text or Element. data Node -- | Case analysis for a Node. node :: (Text -> HashMap Text Text -> [Node] -> a) -> (Text -> a) -> Node -> a -- | Destruct an element Node. pattern Element :: Text -> HashMap Text Text -> [Node] -> Node -- | Construct a XML fragment body containing a single Element -- Node, if possible. -- -- This function will return empty list if it is not possible to -- construct the Element with the given input. To learn more about -- why it was not possible to construct it, use element -- instead. -- -- Using element' rather than element is recommended, so -- that you are forced to acknowledge a failing situation in case it -- happens. However, element is at times more convenient to use, -- whenever you know the input is valid. element :: Text -> HashMap Text Text -> [Node] -> [Node] -- | Construct an Element Node. -- -- Returns Left if the Element Node can't be -- created, with an explanation of why. element' :: Text -> HashMap Text Text -> [Node] -> Either String Node -- | Destruct a text Node. pattern Text :: Text -> Node -- | Construct a XML fragment body containing a single Text -- Node, if possible. -- -- This function will return empty list if it is not possible to -- construct the Text with the given input. To learn more about -- why it was not possible to construct it, use text' -- instead. -- -- Using text' rather than text is recommended, so that you -- are forced to acknowledge a failing situation in case it happens. -- However, text is at times more convenient to use. For example, -- when you know statically the input is valid. text :: Text -> [Node] -- | Construct a Text Node, if possible. -- -- Returns Left if the Text Node can't be created, -- with an explanation of why. text' :: Text -> Either String Node -- | Post-order depth-first replacement of Node and all of its -- children. -- -- This function works like fix, but the given function is trying -- to find a fixpoint for the individual children nodes, not for the root -- node. -- -- For example, the following function renames every node named -- "w" to "y", and every node named "y" to -- "z". It accomplishes this by first renaming "w" -- nodes to "x", and then, by using k recursively to -- further rename all "x" nodes (including the ones that were -- just created) to "y" in a post-order depth-first manner. -- After renaming an "x" node to "y", the recursion -- stops (i.e., k is not used), so our new "y" nodes -- won't be further renamed to "z". However, nodes that were -- named "y" initially will be renamed to "z". -- -- In our example we only replace one node with another, but a node can -- be replaced with zero or more nodes, depending on the length of the -- resulting list. -- --
-- foo :: Node -> [Node] -- foo = dfpos $ \k -> \case -- Element "w" as cs -> element "x" as cs >>= k -- Element "x" as cs -> element "y" as cs -- Element "y" as cs -> element "z" as cs >>= k ---- -- See dfpre for pre-orderd depth-first replacement. -- -- WARNING If you call k in every branch, then -- dfpos will never terminate. Make sure the recursion stops at -- some point by simply returning a list of nodes instead of calling -- k. dfpos :: ((Node -> [Node]) -> Node -> [Node]) -> Node -> [Node] -- | Monadic version of dfpos. dfposM :: Monad m => ((Node -> m [Node]) -> Node -> m [Node]) -> Node -> m [Node] -- | Pre-order depth-first replacement of Node and all of its -- children. -- -- This is just like dfpos but the search proceeds in a different -- order. dfpre :: ((Node -> [Node]) -> Node -> [Node]) -> Node -> [Node] -- | Monadic version of dfpre. dfpreM :: Monad m => ((Node -> m [Node]) -> Node -> m [Node]) -> Node -> m [Node] class FromXml a -- | Parses an XML fragment body into a value of type a. -- -- If a ToXml instance for a exists, then: -- --
-- runParser fromXml (toXml a) == pure (Right a) --fromXml :: FromXml a => Parser a class ToXml a -- | Renders a value of type a into an XML fragment body. -- -- If a FromXml instance for a exists, then: -- --
-- runParser fromXml (toXml a) == Right a --toXml :: ToXml a => a -> [Node] instance GHC.Classes.Eq Xmlbf.Node instance GHC.Base.Semigroup a => GHC.Base.Semigroup (Xmlbf.Parser a) instance GHC.Base.Monoid a => GHC.Base.Monoid (Xmlbf.Parser a) instance GHC.Base.Functor Xmlbf.Parser instance GHC.Base.Applicative Xmlbf.Parser instance GHC.Base.Alternative Xmlbf.Parser instance Control.Selective.Selective Xmlbf.Parser instance GHC.Base.Monad Xmlbf.Parser instance Control.Monad.Fail.MonadFail Xmlbf.Parser instance GHC.Base.MonadPlus Xmlbf.Parser instance Control.Monad.Fix.MonadFix Xmlbf.Parser instance Control.Monad.Zip.MonadZip Xmlbf.Parser instance Control.DeepSeq.NFData Xmlbf.Node instance GHC.Show.Show Xmlbf.Node