/
ValidationTypes.hs
213 lines (162 loc) · 5.95 KB
/
ValidationTypes.hs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
{-# LANGUAGE TypeSynonymInstances, FlexibleInstances #-}
{-# OPTIONS -fno-warn-orphans #-}
{- |
Module : Text.XML.HXT.XMLSchema.ValidationTypes
Copyright : Copyright (C) 2012 Thorben Guelck, Uwe Schmidt
License : MIT
Maintainer : Uwe Schmidt (uwe@fh-wedel.de)
Stability : experimental
Portability: portable
Contains the basic datatypes which are used during validation.
-}
module Text.XML.HXT.XMLSchema.ValidationTypes
where
import Text.XML.HXT.Core ( QName
, XmlTree
, c_warn
, c_err
)
import Text.XML.HXT.DOM.ShowXml ( xshow )
-- import Text.XML.HXT.Arrow.XmlRegex ( XmlRegex )
import Control.Monad.Identity ( Identity
, runIdentity
)
import Control.Monad.Reader ( ReaderT
, runReaderT
, asks
)
import Control.Monad.Writer ( WriterT
, runWriterT
, tell
)
import Data.Map ( Map
, keys
)
import Text.XML.HXT.XMLSchema.Regex
-- ----------------------------------------
-- | The environment used during validation
data SValEnv = SValEnv
{ xpath :: XPath
, elemDesc :: ElemDesc
, allElemDesc :: SubElemDesc -- all declared elements, used with wilcard contents
}
-- | Simple XPath representation
type XPath = String
-- | Description for an element under test
data ElemDesc = ElemDesc
{ errmsg :: Maybe String
, attrDesc :: AttrDesc
, mixedContent :: Bool
, contentModel :: XmlRegex'
, subElemDesc :: SubElemDesc
, wildcards :: Wildcards -- redundant: never read, only set
, sttf :: MaybeSTTF -- in case of simple types Just the string test, else Nothing
}
-- | Description for allowed attributes of an element
type AttrDesc = (AttrMap, AttrWildcards)
-- | Table for regular attributes
type AttrMap = Map QName AttrMapVal
-- | Entry for AttrMap: required-flag and test function
type AttrMapVal = (Bool, STTF)
-- | List of test functions for attribute wildcards
type AttrWildcards = [QName -> Bool]
-- | Table of possible subelems and their descriptions
type SubElemDesc = Map QName ElemDesc
-- | List of wildcard specs
type Wildcards = [Wildcard]
-- | Pair of namespace test and action
data Wildcard = WC (QName -> Bool) WildcardClass
-- | wildcard validation strategie
data WildcardClass = Skip | Lax | Strict
-- | SimpleType test function to validate basic values
type STTF = String -> SVal Bool
-- | SimpleType test function to validate basic values
type MaybeSTTF = Maybe STTF
-- | Validation result contains the validation status and log
type SValResult = (Bool, SValLog)
-- | Validation log is a list of error levels, XPaths and messages
type SValLog = [SValLogMsg]
-- | Validation log message
type SValLogMsg = (Int, XPath, String)
-- | Schema validation monad
type SVal a = ReaderT SValEnv (WriterT SValLog Identity) a
-- | Runs a computation in the schema validation monad
runSVal :: SValEnv -> SVal a -> (a, SValLog)
runSVal env val = runIdentity $ runWriterT $ runReaderT val env
-- | the result state of a matching test with XmlTree regular expressions
--
-- the result is a function for testing the content model of all elements
-- contained in the children of an element
type XmlRegexState = SVal Bool
-- | A substitute for XmlRegex from hxt Arrow.XmlRegex
type XmlRegex' = Regex XmlRegexState XmlTree
instance ShowSym XmlTree where
showSym = cut 80 . xshow . (:[])
cut :: Int -> String -> String
cut n s
| null rest = s'
| otherwise = s' ++ "..."
where
(s', rest) = splitAt n s
-- ----------------------------------------
-- | Creates a SimpleType test function which creates a warning and always succeeds
mkWarnSTTF :: String -> STTF
mkWarnSTTF msg
= \ _ -> mkLogSTTF c_warn id msg
mkWarnSTTF'' :: (XPath -> XPath) -> String -> SVal Bool
mkWarnSTTF''
= mkLogSTTF c_warn
-- | Creates a SimpleType test function which creates an error and always fails
mkErrorSTTF :: String -> STTF
mkErrorSTTF msg
= \ _ -> mkErrorSTTF' msg
mkErrorSTTF' :: STTF
mkErrorSTTF' msg
= mkLogSTTF c_err id msg
mkErrorSTTF'' :: (XPath -> XPath) -> String -> SVal Bool
mkErrorSTTF''
= mkLogSTTF c_err
mkLogSTTF :: Int -> (XPath -> XPath) -> String -> SVal Bool
mkLogSTTF lev fpos msg
= do pos <- asks xpath
tell [(lev, fpos pos, msg)]
return (lev < c_err)
-- ----------------------------------------
--
-- simple tracing
-- {-
logg :: [String] -> SVal ()
logg msg
= do pos <- asks xpath
tell [(0, pos, unwords msg)]
-- -}
{-
logg :: [String] -> SVal ()
logg msg
= return ()
{-# INLINE #-}
-- -}
showElemDesc :: ElemDesc -> String
showElemDesc e
= unwords [ "ElemDesc {"
, show $ errmsg e
, ",attrDesc ="
, showAttrDesc $ attrDesc e
, ",mixedDontent ="
, show $ mixedContent e
, ",contentModel ="
, show $ contentModel e
, ",subElemDesc = "
, show . keys $ subElemDesc e
, ",sttf ="
, show . fmap (const "<sttf>") $ sttf e
]
showAttrDesc :: AttrDesc -> String
showAttrDesc a
= unwords [ "("
, show . keys . fst $ a
, ","
, show . map (const "<wcf>") . snd $ a
, ")"
]
-- ----------------------------------------