@@ -15,27 +15,13 @@ module Text.XML.DOM.Parser.Combinators
15 , ignoreElem
15 , ignoreElem
16 , ignoreEmpty
16 , ignoreEmpty
17 , ignoreBlank
17 , ignoreBlank
18− -- * Getting current element's properties
21− , getCurrentAttributes
22− , getCurrentAttribute
23− -- * Current element's checks
25− -- * Parsing element's content
27− -- * Parsing attributes
29− , parseAttributeMaybe
32import Control.Lens
20import Control.Lens
33−import Control.Monad.Except
34import Control.Monad.Reader
21import Control.Monad.Reader
35import Data.Foldable as F
22import Data.Foldable as F
36import Data.List as L
23import Data.List as L
37import Data.List.NonEmpty (NonEmpty(..))
24import Data.List.NonEmpty (NonEmpty(..))
38−import Data.Map.Strict as M
39import Data.Monoid
25import Data.Monoid
40import Data.Text as T
26import Data.Text as T
41import Data.Traversable
27import Data.Traversable
@@ -68,7 +54,7 @@ traverseElems trav parser = do
69-- | Takes function filtering
55-- | Takes function filtering
70inFilteredTrav
56inFilteredTrav
71− :: (Monad m, Foldable g, DomTraversable f)
57+ :: (Monad m, Foldable g, Buildable f)
72 => ([Element] -> (DomPath, [Element]))
58 => ([Element] -> (DomPath, [Element]))
73 -- ^ Function returning some filtered elements with path suffixes which will
59 -- ^ Function returning some filtered elements with path suffixes which will
74 -- be appended to parser's state
60 -- be appended to parser's state
@@ -78,12 +64,12 @@ inFilteredTrav deeper = traverseElems trav
79 trav e = do
65 trav e = do
80 let (path, elems) = deeper e
66 let (path, elems) = deeper e
81− case buildDomTraversable elems of
67+ case build elems of
82 Nothing -> throwParserError $ PENotFound . (<> path)
68 Nothing -> throwParserError $ PENotFound . (<> path)
83 Just tr -> return $ fmap (path,) tr
69 Just tr -> return $ fmap (path,) tr
86− :: (Monad m, Foldable g, DomTraversable f)
72+ :: (Monad m, Foldable g, Buildable f)
87 => NameMatcher -- ^ Name of tag to traverse in
73 => NameMatcher -- ^ Name of tag to traverse in
88 -> DomParserT Identity m a
74 -> DomParserT Identity m a
89 -> DomParserT g m (f a)
75 -> DomParserT g m (f a)
@@ -205,106 +191,3 @@ ignoreBlank = ignoreElem test
205 in if | not $ L.null elems -> False
191 in if | not $ L.null elems -> False
206 | T.null $ T.strip cont -> True
192 | T.null $ T.strip cont -> True
207 | otherwise -> False
193 | otherwise -> False
209−-- | Returns name of current element.
212−getCurrentName :: (Monad m) => DomParserT Identity m Name
213−getCurrentName = view $ pdElements . to runIdentity . name
215−-- | If name of current tag differs from first argument throws 'PENotFound' with
216−-- tag name replaced in last path's segment. Useful for checking root
217−-- document's element name.
221− -> DomParserT Identity m ()
222−checkCurrentName n = do
223− cn <- getCurrentName
224− unless ((n ^. nmMatch) cn) $ do
226− let pinit = if L.null (unDomPath p) then [] else L.init $ unDomPath p
227− throwError $ ParserErrors [PENotFound $ DomPath $ pinit ++ [_nmShow n]]
230−-- | Get current content. If current element contains no content or
231−-- have inner elements then Nothing returned
234−getCurrentContent :: (Monad m) => DomParserT Identity m (Maybe Text)
235−getCurrentContent = do
236− nds <- view $ pdElements . to runIdentity . nodes
239− els = nds ^.. folded . _Element
241− conts = nds ^.. folded . _Content
243− | not $ L.null els -> Nothing
244− | L.null conts -> Nothing
245− | otherwise -> Just $ mconcat conts
247−-- | Parses content inside current tag. It expects current element set
248−-- consists of exactly ONE element. If current element does not
249−-- contains content or have other elements as childs then throws error
252− => (Text -> Either Text a)
253− -- ^ Content parser, return error msg if value is not parsed
254− -> DomParserT Identity m a
255−parseContent parse = getCurrentContent >>= \case
256− Nothing -> throwParserError PEContentNotFound
257− Just c -> case parse c of
258− Left e -> throwParserError $ PEWrongFormat e
261−-- | Retuns map of attributes of current element
266− => DomParserT Identity m (M.Map Name Text)
267−getCurrentAttributes = view $ pdElements . to runIdentity . attrs
269−-- | Returns element with given name or 'Nothing'
275− -> DomParserT Identity m (Maybe Text)
276−getCurrentAttribute attrName
277− = preview $ pdElements . to runIdentity . attrs . to M.toList
278− . traversed . filtered (views _1 (attrName ^. nmMatch)) . _2
280−-- | Parses attribute with given name, throws error if attribute is not found.
287− -> (Text -> Either Text a)
288− -- ^ Attribute content parser
289− -> DomParserT Identity m a
290−parseAttribute attrName parser =
291− parseAttributeMaybe attrName parser >>= \case
292− Nothing -> throwParserError $ PEAttributeNotFound attrName
295−-- | Parses attribute with given name.
302− -> (Text -> Either Text a)
303− -- ^ Attribute content parser
304− -> DomParserT Identity m (Maybe a)
305−parseAttributeMaybe attrName parser =
306− getCurrentAttribute attrName >>= \case
307− Nothing -> return Nothing
308− Just aval -> case parser aval of
309− Left err -> throwParserError $ PEAttributeWrongFormat attrName err
310− Right a -> return $ Just a