git.iko.soy/typeable/dom-parser
on 7fb1685 help sign in
14 files changed+188−314
since splitsnapshots
unifiedsplit
.travis.yml+5−7 CHANGELOG.md−44 README.md−5 dom-parser.cabal+10−11 ghc-963.yaml−7 src/Text/XML/DOM/Parser.hs+1−3 src/Text/XML/DOM/Parser/Attributes.hs−64 src/Text/XML/DOM/Parser/Combinators.hs+5−13 src/Text/XML/DOM/Parser/Content.hs+118−63 src/Text/XML/DOM/Parser/FromAttribute.hs−2 src/Text/XML/DOM/Parser/FromDom.hs+21−2 src/Text/XML/DOM/Parser/Types.hs+22−46 src/Text/XML/Soap.hs−46 stack.yaml+6−1
.travis.yml+5−7
@@ -4,12 +4,6 @@ sudo: false
44# Do not choose a language; we provide our own build tools.
55language: generic
66
7−env:
8− - STACK_YAML=stack.yaml
9− - STACK_YAML=ghc-802.yaml
10− - STACK_YAML=ghc-822.yaml
11− - STACK_YAML=ghc-841.yaml
12−
137# Caching so the next build will be fast too.
148cache:
159 directories:
@@ -27,6 +21,10 @@ before_install:
2721- export PATH=$HOME/.local/bin:$PATH
2822- travis_retry curl -L https://www.stackage.org/stack/linux-x86_64 | tar xz --wildcards --strip-components=1 -C ~/.local/bin '*/stack'
2923
24+install:
25+# Build dependencies
26+- stack --no-terminal --install-ghc build --only-dependencies
27+
3028script:
3129# Build the package, its tests, and its docs and run the tests
32−- stack --no-terminal --install-ghc test --haddock --no-haddock-deps
30+- stack --no-terminal test --haddock --no-haddock-deps
CHANGELOG.md−44
@@ -1,54 +1,10 @@
11# CHANGELOG
22
3−## HEAD
4−
5−## 3.2.0
6−
7−### Added
8−
9−* Text.XML.Soap module with XmlEnvelope stuff in it.
10−* GHC 9 compatibility.
11−
12−### Removed
13−
14−* Old stackage files.
15−
16−## 3.1.0
17−
18−### Added
19−
20−* Additional builds with GHC 8.0.2 and 8.2.1
21−* Compatibility with GHC 8.4.1
22−
23−## 3.0.0
24−
25−* GHC 8 compatible release
26−
27−### Removed
28−
29−* `open-union` dependency
30−
31−## 2.0.0
32−
33−### Added
34−
35−* `NameMatcher` and `ElemMatcher` as more flexible mechanisms for
36− matching names and elements instead of just matching by name.
37−* Class `FromAttribute` and some default instances
38−
39−### Changed
40−
41−* `DomTraversable` renamed to `Buildable`
42−* Combinators use `NameMatcher` and `ElemMatcher`
43−* Documentation improved
44−
453## 1.0.0
46−
474* Added support for parsing attributes
485* Changed public interface for 'parseContent'
496* Added useful functions
507* Dropped unnecessary dependency from shakespeare
518
529## 0.1.0
53−
5410* Public release
README.mddeleted−5
@@ -1,5 +0,0 @@
1−# dom-parser
2−
3−[![Build Status](https://travis-ci.org/typeable/dom-parser.svg?branch=master)](https://travis-ci.org/typeable/dom-parser)
4−
5−Simple monadic DOM parser
dom-parser.cabal+10−11
@@ -1,5 +1,5 @@
11name: dom-parser
2−version: 3.2.0
2+version: 1.0.0
33synopsis: Simple monadic DOM parser
44license: MIT
55license-file: LICENSE
@@ -7,13 +7,12 @@ author: Typeable.io contributors
77maintainer: makeit@typeable.io
88category: XML
99build-type: Simple
10+extra-source-files: CHANGELOG.md
1011cabal-version: >=1.10
12+
13+extra-source-files: CHANGELOG.md
14+
1115homepage: https://github.com/typeable/dom-parser
12−tested-with: GHC == 9.2.7
13− , GHC == 9.4.8
14− , GHC == 9.6.3
15−extra-source-files: CHANGELOG.md
16− , README.md
1716
1817source-repository head
1918 type: git
@@ -44,26 +43,26 @@ library
4443 , TypeFamilies
4544 , TypeOperators
4645 , UndecidableInstances
47− build-depends: base >= 4.11 && < 5
46+ build-depends: base >= 4.7 && < 5
4847 , case-insensitive
4948 , containers
5049 , lens
51− , mtl < 2.3 || > 2.3
50+ , mtl
51+ , open-union >= 0.2
5252 , scientific
53+ , semigroups
5354 , text
5455 , transformers
56+ , type-fun
5557 , xml-conduit
56− , xml-conduit-writer
5758 , xml-lens
5859 exposed-modules: Text.XML.DOM.Parser
59− , Text.XML.DOM.Parser.Attributes
6060 , Text.XML.DOM.Parser.Buildable
6161 , Text.XML.DOM.Parser.Combinators
6262 , Text.XML.DOM.Parser.Content
6363 , Text.XML.DOM.Parser.FromAttribute
6464 , Text.XML.DOM.Parser.FromDom
6565 , Text.XML.DOM.Parser.Types
66− , Text.XML.Soap
6766
6867test-suite test
6968 type: exitcode-stdio-1.0
ghc-963.yamldeleted−7
@@ -1,7 +0,0 @@
1−resolver: lts-22.6
2−
3−extra-deps:
4− - xml-conduit-writer-0.1.1.5
5−
6−nix:
7− packages: [zlib]
src/Text/XML/DOM/Parser.hs+1−3
@@ -1,6 +1,5 @@
11module Text.XML.DOM.Parser
2− ( module Text.XML.DOM.Parser.Attributes
3− , module Text.XML.DOM.Parser.Buildable
2+ ( module Text.XML.DOM.Parser.Buildable
43 , module Text.XML.DOM.Parser.Combinators
54 , module Text.XML.DOM.Parser.Content
65 , module Text.XML.DOM.Parser.FromAttribute
@@ -8,7 +7,6 @@ module Text.XML.DOM.Parser
87 , module Text.XML.DOM.Parser.Types
98 ) where
109
11−import Text.XML.DOM.Parser.Attributes
1210import Text.XML.DOM.Parser.Buildable
1311import Text.XML.DOM.Parser.Combinators
1412import Text.XML.DOM.Parser.Content
src/Text/XML/DOM/Parser/Attributes.hsdeleted−64
@@ -1,64 +0,0 @@
1−module Text.XML.DOM.Parser.Attributes
2− ( parseAttribute
3− , parseAttributeMaybe
4− , getCurrentAttributes
5− , getCurrentAttribute
6− ) where
7−
8−import Control.Lens
9−import Data.Map.Strict as M
10−import Data.Text as T
11−import Text.XML.DOM.Parser.Types
12−import Text.XML.Lens
13−
14−-- | Parses attribute with given name, throws error if attribute is not found.
15−--
16−-- @since 1.0.0
17−parseAttribute
18− :: (Monad m)
19− => NameMatcher
20− -- ^ Attribute name
21− -> (Text -> Either Text a)
22− -- ^ Attribute content parser
23− -> DomParserT Identity m a
24−parseAttribute attrName parser =
25− parseAttributeMaybe attrName parser >>= \case
26− Nothing -> throwParserError $ PEAttributeNotFound attrName
27− Just a -> return a
28−
29−-- | Parses attribute with given name. Returns Nothing if attribute is
30−-- not found.
31−--
32−-- @since 1.0.0
33−parseAttributeMaybe
34− :: (Monad m)
35− => NameMatcher
36− -- ^ Attribute name
37− -> (Text -> Either Text a)
38− -- ^ Attribute content parser
39− -> DomParserT Identity m (Maybe a)
40−parseAttributeMaybe attrName parser =
41− getCurrentAttribute attrName >>= \case
42− Nothing -> return Nothing
43− Just aval -> case parser aval of
44− Left err -> throwParserError $ PEAttributeWrongFormat attrName err
45− Right a -> return $ Just a
46−
47−-- | Retuns map of attributes of current element
48−--
49−-- @since 1.0.0
50−getCurrentAttributes
51− :: (Monad m)
52− => DomParserT Identity m (M.Map Name Text)
53−getCurrentAttributes = view $ pdElements . to runIdentity . attrs
54−
55−-- | Returns element with given name or 'Nothing'
56−--
57−-- @since 1.0.0
58−getCurrentAttribute
59− :: (Monad m)
60− => NameMatcher
61− -> DomParserT Identity m (Maybe Text)
62−getCurrentAttribute attrName
63− = preview $ pdElements . to runIdentity . attrs . to M.toList
64− . traversed . filtered (views _1 (attrName ^. nmMatch)) . _2
src/Text/XML/DOM/Parser/Combinators.hs+5−13
@@ -22,6 +22,7 @@ import Control.Monad.Reader
2222import Data.Foldable as F
2323import Data.List as L
2424import Data.List.NonEmpty (NonEmpty(..))
25+import Data.Monoid
2526import Data.Text as T
2627import Data.Traversable
2728import Text.XML
@@ -67,13 +68,9 @@ inFilteredTrav deeper = traverseElems trav
6768 Nothing -> throwParserError $ PENotFound . (<> path)
6869 Just tr -> return $ fmap (path,) tr
6970
70−-- | Runs parser arbitrary times, depending on 'Buildable' instance of
71−-- 'f'. For example if 'f' becomes 'NonEmpty' then 'inElemTrav' finds
72−-- @one or more@ elements matched by given 'ElemMatcher' and run
73−-- parser in each found element, then returns @NonEmpty a@ of results.
7471inElemTrav
7572 :: (Monad m, Foldable g, Buildable f)
76− => ElemMatcher -- ^ Tag(s) matcher to traverse in
73+ => ElemMatcher -- ^ Name of tag to traverse in
7774 -> DomParserT Identity m a
7875 -> DomParserT g m (f a)
7976inElemTrav n = inFilteredTrav deeper
@@ -81,7 +78,7 @@ inElemTrav n = inFilteredTrav deeper
8178 elemsFold = folded . nodes . folded . _Element . elMatch n
8279 deeper = (DomPath [_emShow n],) . toListOf elemsFold
8380
84−-- | Runs parser inside first children element matched by macher
81+-- | Runs parser inside first children element with given name
8582inElem
8683 :: (Monad m, Foldable g)
8784 => ElemMatcher
@@ -111,10 +108,10 @@ inElemNe
111108inElemNe = inElemTrav
112109
113110{- | Dive given parser's current tags set into the given path. The @divePath
114−["a", "b"]@ differs from @inElem "a" $ inElem "b"@. Namely the first variant
111+["a", "b"]@ differs from @inElem "a" . inElem "b"@. Namely the first variant
115112will not fail if occured tag "a" which does not contains tag "b". This
116113behaviour is desireable when you dont want to parse whole XML and just want
117−to pull tags located in some path. The other difference is in traversing inner
114+to pull tags in some path. The other difference is in traversing inner
118115elements. Consider this code
119116
120117@
@@ -132,11 +129,6 @@ which translates like: @a > b > c > fromDom@
132129As you can see, inElem always takes first element and runs inner parser in this
133130single element, unlike 'divePath' which runs inner parser @in all@ descendants
134131in given path.
135−
136−Note also that 'divePath' takes parser parameterized by @[]@ not by
137−'Identity'. This because when you dive using some path you will get a
138−list of found elements and all these elements will be @current@ for
139−parser.
140132-}
141133
142134divePath
src/Text/XML/DOM/Parser/Content.hs+118−63
@@ -1,44 +1,84 @@
11module Text.XML.DOM.Parser.Content
2− (
3− -- * Parsing element's content
4− parseContent
2+ ( -- * Content readers
3+ readBool
4+ , readChar
5+ -- ** Reader constructors
6+ , maybeReadContent
7+ , readContent
58 -- * Getting current element's properties
69 , getCurrentName
710 , getCurrentContent
11+ , getCurrentAttributes
12+ , getCurrentAttribute
813 , checkCurrentName
9− -- * Internal
10− , maybeReadContent
11− , readContent
12− , readBool
13− , readChar
14+ -- * Parsing element's content
15+ , parseContent
16+ -- * Parsing attributes
17+ , parseAttribute
18+ , parseAttributeMaybe
1419 ) where
1520
1621import Control.Lens
1722import Control.Monad
1823import Control.Monad.Except
1924import Data.List as L
25+import Data.Map.Strict as M
2026import Data.Monoid
2127import Data.Text as T
2228import Data.Typeable
23−import Prelude as P
2429import Text.Read
2530import Text.XML.DOM.Parser.Types
2631import Text.XML.Lens
2732
2833
29−-- | Parses content inside current tag. It expects current element set
30−-- consists of exactly ONE element.
31−parseContent
32− :: (Monad m)
33− => (Text -> Either Text a)
34− -- ^ Content parser, return error msg if value is not parsed
35− -> DomParserT Identity m a
36−parseContent parse = getCurrentContent >>= \case
37− Nothing -> throwParserError PEContentNotFound
38− Just c -> case parse c of
39− Left e -> throwParserError $ PEContentWrongFormat e
40− Right a -> return a
34+-- | @since 1.0.0
35+readBool :: Text -> Either Text Bool
36+readBool t =
37+ let
38+ lowt = T.toLower $ T.strip t
39+ tvals = ["y", "yes", "t", "true", "1"]
40+ fvals = ["n", "no", "f", "false", "0"]
41+ in if
42+ | lowt `elem` tvals -> Right True
43+ | lowt `elem` fvals -> Right False
44+ | otherwise ->
45+ Left $ "Could not read " <> t <> " as Bool"
4146
47+-- | Expects text to be single character
48+--
49+-- @since 1.0.0
50+readChar :: Text -> Either Text Char
51+readChar t = case T.unpack $ T.strip t of
52+ [c] -> Right c
53+ _ -> Left "Should have exactly one non-blank character"
54+
55+-- | If reader returns 'Nothing' then resulting function returns 'Left
56+-- "error message"'. 'Typeable' is used for generating usefull error
57+-- message.
58+--
59+-- @since 1.0.0
60+maybeReadContent
61+ :: forall a
62+ . (Typeable a)
63+ => (Text -> Maybe a)
64+ -- ^ Content or attribute reader
65+ -> Text
66+ -- ^ Content or attribute value
67+ -> Either Text a
68+maybeReadContent f t = maybe (Left msg) Right $ f t
69+ where
70+ msg = "Not readable " <> n <> ": " <> t
71+ n = T.pack $ show $ typeRep (Proxy :: Proxy a)
72+
73+
74+-- | Tries to read given text to value using 'Read'. Useful to use
75+-- with 'parseContent' and 'parseAttribute'. Content is stripped
76+-- before reading.
77+readContent
78+ :: (Read a, Typeable a)
79+ => Text
80+ -> Either Text a
81+readContent = maybeReadContent $ readMaybe . T.unpack . T.strip
4282
4383-- | Returns name of current element.
4484--
@@ -78,52 +118,67 @@ getCurrentContent = do
78118 | L.null conts -> Nothing
79119 | otherwise -> Just $ mconcat conts
80120
81−-- | If reader returns 'Nothing' then resulting function returns 'Left
82−-- "error message"'. 'Typeable' is used for generating usefull error
83−-- message.
121+-- | Parses content inside current tag. It expects current element set
122+-- consists of exactly ONE element.
123+parseContent
124+ :: (Monad m)
125+ => (Text -> Either Text a)
126+ -- ^ Content parser, return error msg if value is not parsed
127+ -> DomParserT Identity m a
128+parseContent parse = getCurrentContent >>= \case
129+ Nothing -> throwParserError PEContentNotFound
130+ Just c -> case parse c of
131+ Left e -> throwParserError $ PEWrongFormat e
132+ Right a -> return a
133+
134+-- | Retuns map of attributes of current element
84135--
85136-- @since 1.0.0
86−maybeReadContent
87− :: forall a
88− . (Typeable a)
89− => (Text -> Maybe a)
90− -- ^ Content or attribute reader
91− -> Text
92− -- ^ Content or attribute value
93− -> Either Text a
94−maybeReadContent f t = maybe (Left msg) Right $ f t
95− where
96− msg = "Not readable " <> n <> ": " <> t
97− n = T.pack $ P.show $ typeRep (Proxy :: Proxy a)
98−
99−
100−-- | Tries to read given text to value using 'Read'. Useful to use
101−-- with 'parseContent' and 'parseAttribute'. Content is stripped
102−-- before reading.
103−readContent
104− :: (Read a, Typeable a)
105− => Text
106− -> Either Text a
107−readContent = maybeReadContent $ readMaybe . T.unpack . T.strip
137+getCurrentAttributes
138+ :: (Monad m)
139+ => DomParserT Identity m (M.Map Name Text)
140+getCurrentAttributes = view $ pdElements . to runIdentity . attrs
108141
142+-- | Returns element with given name or 'Nothing'
143+--
144+-- @since 1.0.0
145+getCurrentAttribute
146+ :: (Monad m)
147+ => NameMatcher
148+ -> DomParserT Identity m (Maybe Text)
149+getCurrentAttribute attrName
150+ = preview $ pdElements . to runIdentity . attrs . to M.toList
151+ . traversed . filtered (views _1 (attrName ^. nmMatch)) . _2
109152
110−-- | @since 1.0.0
111−readBool :: Text -> Either Text Bool
112−readBool t =
113− let
114− lowt = T.toLower $ T.strip t
115− tvals = ["y", "yes", "t", "true", "1"]
116− fvals = ["n", "no", "f", "false", "0"]
117− in if
118− | lowt `L.elem` tvals -> Right True
119− | lowt `L.elem` fvals -> Right False
120− | otherwise ->
121− Left $ "Could not read " <> t <> " as Bool"
153+-- | Parses attribute with given name, throws error if attribute is not found.
154+--
155+-- @since 1.0.0
156+parseAttribute
157+ :: (Monad m)
158+ => NameMatcher
159+ -- ^ Attribute name
160+ -> (Text -> Either Text a)
161+ -- ^ Attribute content parser
162+ -> DomParserT Identity m a
163+parseAttribute attrName parser =
164+ parseAttributeMaybe attrName parser >>= \case
165+ Nothing -> throwParserError $ PEAttributeNotFound attrName
166+ Just a -> return a
122167
123−-- | Expects text to be single character
168+-- | Parses attribute with given name. Returns Nothing if attribute is
169+-- not found.
124170--
125171-- @since 1.0.0
126−readChar :: Text -> Either Text Char
127−readChar t = case T.unpack $ T.strip t of
128− [c] -> Right c
129− _ -> Left "Should have exactly one non-blank character"
172+parseAttributeMaybe
173+ :: (Monad m)
174+ => NameMatcher
175+ -- ^ Attribute name
176+ -> (Text -> Either Text a)
177+ -- ^ Attribute content parser
178+ -> DomParserT Identity m (Maybe a)
179+parseAttributeMaybe attrName parser =
180+ getCurrentAttribute attrName >>= \case
181+ Nothing -> return Nothing
182+ Just aval -> case parser aval of
183+ Left err -> throwParserError $ PEAttributeWrongFormat attrName err
184+ Right a -> return $ Just a
src/Text/XML/DOM/Parser/FromAttribute.hs−2
@@ -26,8 +26,6 @@ import Text.XML.DOM.Parser.Content
2626-- | Class of types which can be get from attribute value. Method
2727-- 'fromAttribute' is a convenient default parameter for
2828-- 'parseAttribute'
29−--
30−-- @since 2.0.0
3129class FromAttribute a where
3230 fromAttribute
3331 :: Text
src/Text/XML/DOM/Parser/FromDom.hs+21−2
@@ -4,6 +4,7 @@ module Text.XML.DOM.Parser.FromDom
44 , proxyFromDom
55 -- * Explicit methods for convenience
66 , elementFromDom
7+ , unionFromDom
78 , textFromDom
89 , stringFromDom
910 , charFromDom
@@ -20,6 +21,7 @@ module Text.XML.DOM.Parser.FromDom
2021import Control.Applicative
2122import Control.Lens
2223import Data.Fixed
24+import Data.OpenUnion
2325import Data.Scientific
2426import Data.Text as T hiding (empty)
2527import Data.Typeable
@@ -27,6 +29,7 @@ import Data.Void
2729import Text.XML
2830import Text.XML.DOM.Parser.Content
2931import Text.XML.DOM.Parser.Types
32+import TypeFun.Data.List hiding (Union)
3033
3134proxyFromDom
3235 :: forall proxy m a
@@ -35,8 +38,7 @@ proxyFromDom
3538 -> DomParserT Identity m a
3639proxyFromDom _ = fromDom
3740
38−-- | Class of types which can be parsed from single XML element. The
39−-- method 'fromDom' is convenient default to use with 'inElem'
41+-- | Class of types which can be parsed from single XML element.
4042class FromDom a where
4143 fromDom :: (Monad m) => DomParserT Identity m a
4244
@@ -113,6 +115,23 @@ instance FromDom Bool where
113115boolFromDom :: (Monad m) => DomParserT Identity m Bool
114116boolFromDom = parseContent readBool
115117
118+instance FromDom (Union '[]) where
119+ fromDom = empty
120+
121+instance
122+ ( Typeable a, FromDom a, FromDom (Union as)
123+ , SubList as (a ': as) )
124+ => FromDom (Union (a ': as)) where
125+ -- fromDom :: forall m. (DomParserMonad m) => m a
126+ fromDom = (liftUnion <$> (proxyFromDom (Proxy :: Proxy a)))
127+ <|> (reUnion <$> (proxyFromDom (Proxy :: Proxy (Union as))))
128+
129+unionFromDom
130+ :: (Monad m, FromDom (Union as))
131+ => proxy as
132+ -> DomParserT Identity m (Union as)
133+unionFromDom _ = fromDom
134+
116135instance FromDom Element where
117136 fromDom = elementFromDom
118137
src/Text/XML/DOM/Parser/Types.hs+22−46
@@ -1,17 +1,17 @@
11module Text.XML.DOM.Parser.Types
2− (-- * Element matching
3− ElemMatcher(..)
4− , emMatch
5− , emShow
6− , matchElemName
7− , elMatch
8− -- * Name matching
9− , NameMatcher(..)
2+ ( -- * Name matching
3+ NameMatcher(..)
104 , nmMatch
115 , nmShow
126 , matchName
137 , matchLocalName
148 , matchCILocalName
9+ -- * Element matching
10+ , ElemMatcher(..)
11+ , emMatch
12+ , emShow
13+ , matchElemName
14+ , elMatch
1515 -- * Parser internals
1616 , DomPath(..)
1717 , ParserError(..)
@@ -43,17 +43,13 @@ import Text.XML
4343import Text.XML.Lens
4444
4545-- | Arbitrary element matcher
46−--
47−-- @since 2.0.0
4846data ElemMatcher = ElemMatcher
4947 { _emMatch :: Element -> Bool
5048 , _emShow :: Text
51− -- ^ Field for 'Show' instance and bulding usefull errors
5249 }
5350
5451makeLenses ''ElemMatcher
5552
56−-- | Instance using instance of 'NameMatcher'
5753instance IsString ElemMatcher where
5854 fromString = matchElemName . fromString
5955
@@ -61,37 +57,29 @@ instance Show ElemMatcher where
6157 show = T.unpack . _emShow
6258
6359-- | Match element by name
64−--
65−-- @since 2.0.0
6660matchElemName :: NameMatcher -> ElemMatcher
6761matchElemName (NameMatcher matchName showName) = ElemMatcher
6862 { _emMatch = views name matchName
6963 , _emShow = showName
7064 }
7165
72−-- | Match over elements
73−--
74−-- @since 2.0.0
7566elMatch :: ElemMatcher -> Traversal' Element Element
7667elMatch (ElemMatcher match _) = filtered match
7768
7869-- | Arbitrary name matcher. Match name any way you want, but
7970-- considered to be used as comparator with some name with some rules
80−--
81−-- @since 2.0.0
8271data NameMatcher = NameMatcher
8372 { _nmMatch :: Name -> Bool
8473 -- ^ Name matching function, usually should be simple comparsion
8574 -- function takin in account only local name or other components
8675 -- of 'Name'
8776 , _nmShow :: Text
88− -- ^ Field for 'Show' instance and bulding usefull errors
77+ -- ^ How to show the name matcher, since there is no 'Read'
78+ -- instance we can do it any way we want
8979 }
9080
91−-- | Instance use 'matchCILocalName' as most general and liberal
92−-- matching strategy (while XML is often malformed).
93−--
94−-- @since 2.0.0
81+makeLenses ''NameMatcher
82+
9583instance IsString NameMatcher where
9684 fromString = matchCILocalName . T.pack
9785
@@ -100,8 +88,6 @@ instance Show NameMatcher where
10088
10189-- | Makes matcher which matches only local part of name igoring
10290-- namespace and prefix. Local name matching is case sensitive.
103−--
104−-- @since 2.0.0
10591matchLocalName :: Text -> NameMatcher
10692matchLocalName tname = NameMatcher
10793 { _nmMatch = \n -> nameLocalName n == tname
@@ -111,19 +97,13 @@ matchLocalName tname = NameMatcher
11197-- | Makes matcher which matches only local part of name igoring
11298-- namespace and prefix. Local name matching is case insensitive. This
11399-- is the most common case.
114−--
115−-- @since 2.0.0
116100matchCILocalName :: Text -> NameMatcher
117101matchCILocalName tname = NameMatcher
118102 { _nmMatch = \n -> CI.mk (nameLocalName n) == CI.mk tname
119103 , _nmShow = tname
120104 }
121105
122−makeLenses ''NameMatcher
123−
124106-- | Makes matcher which match name by 'Eq' with given
125−--
126−-- @since 2.0.0
127107matchName :: Name -> NameMatcher
128108matchName n = NameMatcher
129109 { _nmMatch = (== n)
@@ -134,7 +114,7 @@ matchName n = NameMatcher
134114-- element of the document. Errors are much more usefull with path.
135115newtype DomPath = DomPath
136116 { unDomPath :: [Text]
137− } deriving (Eq, Ord, Show, Semigroup, Monoid)
117+ } deriving (Eq, Ord, Show, Monoid)
138118
139119-- | DOM parser error description.
140120data ParserError
@@ -144,17 +124,13 @@ data ParserError
144124 -- ^ Path of element error occured in
145125 }
146126
147− -- | Expected attribute but not found
148− --
149− -- @since 1.0.0
150− | PEAttributeNotFound
151− { _peAttributeName :: NameMatcher
152− , _pePath :: DomPath
127+ -- | Tag contents has wrong format, (could not read text to value)
128+ | PEWrongFormat
129+ { _peDetails :: Text
130+ , _pePath :: DomPath
153131 }
154132
155133 -- | Could not parse attribute
156− --
157− -- @since 1.0.0
158134 | PEAttributeWrongFormat
159135 { _peAttributeName :: NameMatcher
160136 , _peDetails :: Text
@@ -166,10 +142,10 @@ data ParserError
166142 { _pePath :: DomPath
167143 }
168144
169− -- | Tag contents has wrong format, (could not read text to value)
170− | PEContentWrongFormat
171− { _peDetails :: Text
172− , _pePath :: DomPath
145+ -- | Expected attribute but not found
146+ | PEAttributeNotFound
147+ { _peAttributeName :: NameMatcher
148+ , _pePath :: DomPath
173149 }
174150
175151 -- | Some other error
@@ -184,7 +160,7 @@ instance Exception ParserError
184160
185161newtype ParserErrors = ParserErrors
186162 { unParserErrors :: [ParserError]
187− } deriving (Show, Semigroup, Monoid, Generic)
163+ } deriving (Show, Monoid, Generic)
188164
189165makePrisms ''ParserErrors
190166
src/Text/XML/Soap.hsdeleted−46
@@ -1,46 +0,0 @@
1−module Text.XML.Soap where
2−
3−import Control.Lens
4−import Data.String
5−import Text.XML
6−import Text.XML.DOM.Parser
7−import Text.XML.Writer
8−
9−data XmlEnvelope h b = XmlEnvelope
10− { _xeHeader :: !(Maybe h)
11− , _xeBody :: !(Maybe b)
12− } deriving (Eq, Show)
13−
14−makeLenses ''XmlEnvelope
15−
16−xmlEnvelopeToDocument :: (ToXML h, ToXML b) => XmlEnvelope h b -> Document
17−xmlEnvelopeToDocument xe = doc
18− where
19− sname n = fromString $ "{http://schemas.xmlsoap.org/soap/envelope/}" <> n
20− doc =
21− Document
22− { documentPrologue = Prologue [] Nothing []
23− , documentRoot =
24− Element
25− { elementName = sname "Envelope"
26− , elementAttributes = mempty
27− , elementNodes = [NodeElement header, NodeElement body]
28− }
29− , documentEpilogue = []
30− }
31− header =
32− Element
33− { elementName = sname "Header"
34− , elementAttributes = mempty
35− , elementNodes = render . toXML $ xe ^. xeHeader
36− }
37− body =
38− Element
39− { elementName = sname "Body"
40− , elementAttributes = mempty
41− , elementNodes = render . toXML $ xe ^. xeBody
42− }
43−
44−instance (FromDom h, FromDom b) => FromDom (XmlEnvelope h b) where
45− fromDom = XmlEnvelope <$> inElemMay "Header" fromDom
46− <*> inElemMay "Body" fromDom
stack.yamlmode 120000 → 100644+6−1
@@ -1 +0,0 @@
1−ghc-963.yaml
@@ -0,0 +1,6 @@
1+packages:
2+ - .
3+extra-deps:
4+ - open-union-0.2.0.0
5+ - type-fun-0.1.1
6+resolver: lts-6.25