@@ -1,17 +1,17 @@
1module Text.XML.DOM.Parser.Types
1module Text.XML.DOM.Parser.Types
2+ (-- * Element matching
2− ( -- * Name matching
8+ -- * Name matching
3− NameMatcher(..)
9+ , NameMatcher(..)
6 , matchName
12 , matchName
7 , matchLocalName
13 , matchLocalName
8 , matchCILocalName
14 , matchCILocalName
15 -- * Parser internals
15 -- * Parser internals
16 , DomPath(..)
16 , DomPath(..)
17 , ParserError(..)
17 , ParserError(..)
@@ -43,13 +43,17 @@ import Text.XML
43import Text.XML.Lens
43import Text.XML.Lens
45-- | Arbitrary element matcher
45-- | Arbitrary element matcher
46data ElemMatcher = ElemMatcher
48data ElemMatcher = ElemMatcher
47 { _emMatch :: Element -> Bool
49 { _emMatch :: Element -> Bool
48 , _emShow :: Text
50 , _emShow :: Text
51+ -- ^ Field for 'Show' instance and bulding usefull errors
51makeLenses ''ElemMatcher
54makeLenses ''ElemMatcher
56+-- | Instance using instance of 'NameMatcher'
53instance IsString ElemMatcher where
57instance IsString ElemMatcher where
54 fromString = matchElemName . fromString
58 fromString = matchElemName . fromString
@@ -57,29 +61,37 @@ instance Show ElemMatcher where
57 show = T.unpack . _emShow
61 show = T.unpack . _emShow
59-- | Match element by name
63-- | Match element by name
60matchElemName :: NameMatcher -> ElemMatcher
66matchElemName :: NameMatcher -> ElemMatcher
61matchElemName (NameMatcher matchName showName) = ElemMatcher
67matchElemName (NameMatcher matchName showName) = ElemMatcher
62 { _emMatch = views name matchName
68 { _emMatch = views name matchName
63 , _emShow = showName
69 , _emShow = showName
72+-- | Match over elements
66elMatch :: ElemMatcher -> Traversal' Element Element
75elMatch :: ElemMatcher -> Traversal' Element Element
67elMatch (ElemMatcher match _) = filtered match
76elMatch (ElemMatcher match _) = filtered match
69-- | Arbitrary name matcher. Match name any way you want, but
78-- | Arbitrary name matcher. Match name any way you want, but
70-- considered to be used as comparator with some name with some rules
79-- considered to be used as comparator with some name with some rules
71data NameMatcher = NameMatcher
82data NameMatcher = NameMatcher
72 { _nmMatch :: Name -> Bool
83 { _nmMatch :: Name -> Bool
73 -- ^ Name matching function, usually should be simple comparsion
84 -- ^ Name matching function, usually should be simple comparsion
74 -- function takin in account only local name or other components
85 -- function takin in account only local name or other components
75 -- of 'Name'
86 -- of 'Name'
76 , _nmShow :: Text
87 , _nmShow :: Text
77− -- ^ How to show the name matcher, since there is no 'Read'
88+ -- ^ Field for 'Show' instance and bulding usefull errors
78− -- instance we can do it any way we want
81−makeLenses ''NameMatcher
91+-- | Instance use 'matchCILocalName' as most general and liberal
82−
92+-- matching strategy (while XML is often malformed).
83instance IsString NameMatcher where
95instance IsString NameMatcher where
84 fromString = matchCILocalName . T.pack
96 fromString = matchCILocalName . T.pack
@@ -88,6 +100,8 @@ instance Show NameMatcher where
89-- | Makes matcher which matches only local part of name igoring
101-- | Makes matcher which matches only local part of name igoring
90-- namespace and prefix. Local name matching is case sensitive.
102-- namespace and prefix. Local name matching is case sensitive.
91matchLocalName :: Text -> NameMatcher
105matchLocalName :: Text -> NameMatcher
92matchLocalName tname = NameMatcher
106matchLocalName tname = NameMatcher
93 { _nmMatch = \n -> nameLocalName n == tname
107 { _nmMatch = \n -> nameLocalName n == tname
@@ -97,13 +111,19 @@ matchLocalName tname = NameMatcher
97-- | Makes matcher which matches only local part of name igoring
111-- | Makes matcher which matches only local part of name igoring
98-- namespace and prefix. Local name matching is case insensitive. This
112-- namespace and prefix. Local name matching is case insensitive. This
99-- is the most common case.
113-- is the most common case.
100matchCILocalName :: Text -> NameMatcher
116matchCILocalName :: Text -> NameMatcher
101matchCILocalName tname = NameMatcher
117matchCILocalName tname = NameMatcher
102 { _nmMatch = \n -> CI.mk (nameLocalName n) == CI.mk tname
118 { _nmMatch = \n -> CI.mk (nameLocalName n) == CI.mk tname
103 , _nmShow = tname
119 , _nmShow = tname
122+makeLenses ''NameMatcher
106-- | Makes matcher which match name by 'Eq' with given
124-- | Makes matcher which match name by 'Eq' with given
107matchName :: Name -> NameMatcher
127matchName :: Name -> NameMatcher
108matchName n = NameMatcher
128matchName n = NameMatcher
109 { _nmMatch = (== n)
129 { _nmMatch = (== n)
@@ -114,7 +134,7 @@ matchName n = NameMatcher
114-- element of the document. Errors are much more usefull with path.
134-- element of the document. Errors are much more usefull with path.
115newtype DomPath = DomPath
135newtype DomPath = DomPath
116 { unDomPath :: [Text]
136 { unDomPath :: [Text]
117− } deriving (Eq, Ord, Show, Monoid)
137+ } deriving (Eq, Ord, Show, Semigroup, Monoid)
119-- | DOM parser error description.
139-- | DOM parser error description.
120data ParserError
140data ParserError
@@ -124,13 +144,17 @@ data ParserError
124 -- ^ Path of element error occured in
144 -- ^ Path of element error occured in
127− -- | Tag contents has wrong format, (could not read text to value)
147+ -- | Expected attribute but not found
128− | PEWrongFormat
148+ --
129− { _peDetails :: Text
149+ -- @since 1.0.0
150+ | PEAttributeNotFound
151+ { _peAttributeName :: NameMatcher
130− , _pePath :: DomPath
152+ , _pePath :: DomPath
133 -- | Could not parse attribute
155 -- | Could not parse attribute
134 | PEAttributeWrongFormat
158 | PEAttributeWrongFormat
135 { _peAttributeName :: NameMatcher
159 { _peAttributeName :: NameMatcher
136 , _peDetails :: Text
160 , _peDetails :: Text
@@ -142,10 +166,10 @@ data ParserError
142 { _pePath :: DomPath
166 { _pePath :: DomPath
145− -- | Expected attribute but not found
169+ -- | Tag contents has wrong format, (could not read text to value)
146− | PEAttributeNotFound
170+ | PEContentWrongFormat
147− { _peAttributeName :: NameMatcher
171+ { _peDetails :: Text
148− , _pePath :: DomPath
172+ , _pePath :: DomPath
151 -- | Some other error
175 -- | Some other error
@@ -160,7 +184,7 @@ instance Exception ParserError
161newtype ParserErrors = ParserErrors
185newtype ParserErrors = ParserErrors
162 { unParserErrors :: [ParserError]
186 { unParserErrors :: [ParserError]
163− } deriving (Show, Monoid, Generic)
187+ } deriving (Show, Semigroup, Monoid, Generic)
165makePrisms ''ParserErrors
189makePrisms ''ParserErrors