git.iko.soy/typeable/xsd-parser
on 1f31ce4 help sign in
10 files changed+86−620
since splitsnapshots
unifiedsplit
.gitmodules−3 README.md−10 src/Xsd.hs+1−1 src/Xsd/Parser.hs+53−158 src/Xsd/Types.hs+17−87 test/Spec.hs+14−46 xsd-parser.cabal+1−13 xsdtests−1 xsts-test/Main.hs−201 xsts.md−100
.gitmodulesdeleted−3
@@ -1,3 +0,0 @@
1−[submodule "xsdtests"]
2− path = xsdtests
3− url = git@github.com:w3c/xsdtests.git
README.mddeleted−10
@@ -1,10 +0,0 @@
1−
2−# xsd-parser
3−
4−Library for parsing XML schema files.
5−
6−# W3C XML Schema 1.1 test suite
7−
8−The test suite is designed mostly to test validation, but at least we
9−can check whether we are able to parse all the xsd files from the
10−test suite. See results [here](xsts.md).
src/Xsd.hs+1−1
@@ -113,7 +113,7 @@ xsdToSchema xsd = Schema
113113 go res [] = res
114114 go (ts, es) (c:cs) = case c of
115115 ChildType n t -> go ((n, t):ts, es) cs
116− ChildElement (Inline e) -> go (ts, (elementName e, e):es) cs
116+ ChildElement e -> go (ts, (elementName e, e):es) cs
117117 _ -> go (ts, es) cs
118118
119119fetchXsd :: URI -> IO Xsd
src/Xsd/Parser.hs+53−158
@@ -48,7 +48,7 @@ parseChild :: Cursor -> P (Maybe Xsd.Child)
4848parseChild c = do
4949 name <- getElementName c
5050 case name of
51− "element" -> Just . Xsd.ChildElement <$> parseElementOrRef c
51+ "element" -> Just . Xsd.ChildElement <$> parseElement c
5252 "simpleType" -> Just <$> parseTopSimpleType c
5353 "complexType" -> Just <$> parseTopComplexType c
5454 "include" -> Just . Xsd.ChildInclude <$> parseInclude c
@@ -81,19 +81,14 @@ parseImport c = do
8181 , Xsd.importNamespace = namespace
8282 }
8383
84−parseElementOrRef :: Cursor -> P (Xsd.RefOr Xsd.Element)
85−parseElementOrRef c = do
86− case anAttribute "ref" c of
87− Nothing -> Xsd.Inline <$> parseElement c
88− Just ref -> Xsd.Ref <$> makeQName c ref
89−
9084parseElement :: Cursor -> P Xsd.Element
9185parseElement c = handleNamespaces c $ do
9286 name <- theAttribute "name" c
9387
88+ -- XXX: generalaze RefOr parsing
9489 tp <- case anAttribute "type" c of
9590 Just t -> Xsd.Ref <$> makeQName c t
96− _ -> maybe (Xsd.Ref anyType) Xsd.Inline <$> parseType c
91+ _ -> Xsd.Inline <$> parseType c
9792
9893 minOccurs <- case anAttribute "minOccurs" c of
9994 Nothing -> return 1
@@ -112,31 +107,22 @@ parseElement c = handleNamespaces c $ do
112107
113108 qname <- makeTargetQName name
114109
115− nillable <- case anAttribute "nillable" c of
116− Nothing -> return False
117− Just "true" -> return True
118− Just "false" -> return False
119− _ -> parseError c "Unexpected value of nillable attribute"
120−
121110 return Xsd.Element
122111 { Xsd.elementName = qname
123112 , Xsd.elementType = tp
124113 , Xsd.elementAnnotations = annotations
125114 , Xsd.elementOccurs = (minOccurs, maxOccurs)
126− , Xsd.elementNillable = nillable
127115 }
128− where
129− anyType = Xsd.QName (Just (Xsd.Namespace Xsd.schemaNamespace)) "anyType"
130116
131117-- | Parse inline type, simple or complex
132−parseType :: Cursor -> P (Maybe Xsd.Type)
118+parseType :: Cursor -> P Xsd.Type
133119parseType c = do
134120 simpleTypeAxis <- makeElemAxis "simpleType"
135121 complexTypeAxis <- makeElemAxis "complexType"
136122 case (c $/ simpleTypeAxis, c $/ complexTypeAxis) of
137− ([], []) -> return Nothing
138− ([t], []) -> Just . Xsd.TypeSimple <$> parseSimpleType t
139− ([], [t]) -> Just . Xsd.TypeComplex <$> parseComplexType t
123+ ([], []) -> parseError c "No type"
124+ ([t], []) -> Xsd.TypeSimple <$> parseSimpleType t
125+ ([], [t]) -> Xsd.TypeComplex <$> parseComplexType t
140126 _ -> parseError c "Multiple types"
141127
142128-- | Top level simple type
@@ -160,19 +146,18 @@ parseSimpleType c = do
160146 unionAxis <- makeElemAxis "union"
161147 case (c $/ restrictionAxis, c $/ listAxis, c $/ unionAxis) of
162148 ([e], [], []) -> Xsd.AtomicType
163− <$> parseSimpleRestriction e
149+ <$> parseRestriction e
164150 <*> parseAnnotations c
165151 ([], [l], []) -> Xsd.ListType
166152 <$> parseList l
167153 <*> parseAnnotations c
168− ([], [], [u]) -> Xsd.UnionType
169− <$> parseUnion u
170− <*> parseAnnotations c
154+ -- TODO implement me
155+ ([], [], [_]) -> parseError c "Not implemented: union"
171156 _ -> parseError c "Expected exactly of of restriction, list or union"
172157
173158-- | Restriction for simple type
174−parseSimpleRestriction :: Cursor -> P Xsd.SimpleRestriction
175−parseSimpleRestriction c = do
159+parseRestriction :: Cursor -> P Xsd.Restriction
160+parseRestriction c = do
176161 -- XXX: generalaze RefOr parsing
177162 tp <- case anAttribute "base" c of
178163 Nothing -> do
@@ -185,9 +170,9 @@ parseSimpleRestriction c = do
185170
186171 constraints <- parseConstrains c
187172
188− return Xsd.SimpleRestriction
189− { Xsd.simpleRestrictionBase = tp
190− , Xsd.simpleRestrictionConstraints = constraints
173+ return Xsd.Restriction
174+ { Xsd.restrictionBase = tp
175+ , Xsd.restrictionConstraints = constraints
191176 }
192177
193178parseConstrains :: Cursor -> P [Xsd.Constraint]
@@ -208,105 +193,30 @@ parseList c =
208193 _ -> parseError c "Multiple types"
209194 Just t -> Xsd.Ref <$> makeQName c t
210195
211−parseUnion :: Cursor -> P [Xsd.RefOr Xsd.SimpleType]
212−parseUnion c =
213− case anAttribute "memberTypes" c of
214− Just list ->
215− mapM (fmap Xsd.Ref . makeQName c) (Text.splitOn " " list)
216− Nothing -> do
217− simpleTypeAxis <- makeElemAxis "simpleType"
218− mapM (fmap Xsd.Inline . parseSimpleType) (c $/ simpleTypeAxis)
219−
220196parseComplexType :: Cursor -> P Xsd.ComplexType
221197parseComplexType c = do
222− annotations <- parseAnnotations c
223− cont <- parseContent c
224− return Xsd.ComplexType
225− { Xsd.complexAnnotations = annotations
226− , Xsd.complexContent = cont
227− }
228−
229−parseContent :: Cursor -> P Xsd.Content
230−parseContent c = do
231− simpleContentAxis <- makeElemAxis "simpleContent"
232− complexContentAxis <- makeElemAxis "complexContent"
233− case (c $/ simpleContentAxis, c $/ complexContentAxis) of
234− ([], []) -> Xsd.ContentPlain <$> parsePlainContent c
235− ([s], []) -> Xsd.ContentSimple <$> parseSimpleContent s
236− ([], [s]) -> Xsd.ContentComplex <$> parseComplexContent s
237− _ -> parseError c
238− "Expected one of simpleContent, complextContent or model group"
239−
240−parsePlainContent :: Cursor -> P Xsd.PlainContent
241−parsePlainContent c = do
242− attributes <- parseAttributes c
243− model <- parseModelGroup c
244− return Xsd.PlainContent
245− { Xsd.plainContentModel = model
246− , Xsd.plainContentAttributes = attributes
247− }
248−
249−parseSimpleContent :: Cursor -> P Xsd.SimpleContent
250−parseSimpleContent c = do
251− restrictionAxis <- makeElemAxis "restriction"
252− extenstionAxis <- makeElemAxis "extension"
253− case (c $/ restrictionAxis, c $/ extenstionAxis) of
254− ([r], []) -> Xsd.SimpleContentRestriction <$> parseSimpleRestriction r
255− ([], [e]) -> Xsd.SimpleContentExtension <$> parseSimpleExtension e
256− _ -> parseError c "Expected one of restriction or extension"
257−
258−parseSimpleExtension :: Cursor -> P Xsd.SimpleExtension
259−parseSimpleExtension c = handleNamespaces c $ do
260− base <- theAttribute "base" c >>= makeQName c
261− attributes <- parseAttributes c
262− return Xsd.SimpleExtension
263− { Xsd.simpleExtensionBase = base
264− , Xsd.simpleExtensionAttributes = attributes
265− }
198+ attrAxis <- makeElemAxis "attribute"
199+ attributes <- mapM parseAttribute (c $/ attrAxis)
200+
201+ group <- do
202+ sequenceAxis <- makeElemAxis "sequence"
203+ choiceAxis <- makeElemAxis "choice"
204+ allAxis <- makeElemAxis "all"
205+ case (c $/ sequenceAxis, c $/ choiceAxis, c $/ allAxis) of
206+ ([], [], []) -> return Nothing
207+ ([g], [], []) -> Just <$> parseSequence g
208+ ([], [g], []) -> Just <$> parseChoice g
209+ ([], [], [g]) -> Just <$> parseAll g
210+ _ -> parseError c "Multiple groups"
266211
267−parseComplexContent :: Cursor -> P Xsd.ComplexContent
268−parseComplexContent c = do
269− restrictionAxis <- makeElemAxis "restriction"
270− extenstionAxis <- makeElemAxis "extension"
271− case (c $/ restrictionAxis, c $/ extenstionAxis) of
272− ([r], []) -> Xsd.ComplexContentRestriction <$> parseComplexRestriction r
273− ([], [e]) -> Xsd.ComplexContentExtension <$> parseComplexExtension e
274− _ -> parseError c "Expected one of restriction or extension"
275−
276−parseComplexExtension :: Cursor -> P Xsd.ComplexExtension
277−parseComplexExtension c = handleNamespaces c $ do
278− base <- theAttribute "base" c >>= makeQName c
279− attributes <- parseAttributes c
280− model <- parseModelGroup c
281− return Xsd.ComplexExtension
282− { Xsd.complexExtensionBase = base
283− , Xsd.complexExtensionModel = model
284− , Xsd.complexExtensionAttributes = attributes
285− }
212+ annotations <- parseAnnotations c
286213
287−parseComplexRestriction :: Cursor -> P Xsd.ComplexRestriction
288−parseComplexRestriction c = handleNamespaces c $ do
289− base <- theAttribute "base" c >>= makeQName c
290− attributes <- parseAttributes c
291− model <- parseModelGroup c
292− return Xsd.ComplexRestriction
293− { Xsd.complexRestrictionBase = base
294− , Xsd.complexRestrictionModel = model
295− , Xsd.complexRestrictionAttributes = attributes
214+ return Xsd.ComplexType
215+ { Xsd.complexAttributes = attributes
216+ , Xsd.complexModelGroup = group
217+ , Xsd.complexAnnotations = annotations
296218 }
297219
298−parseModelGroup :: Cursor -> P (Maybe Xsd.ModelGroup)
299−parseModelGroup c = do
300− sequenceAxis <- makeElemAxis "sequence"
301− choiceAxis <- makeElemAxis "choice"
302− allAxis <- makeElemAxis "all"
303− case (c $/ sequenceAxis, c $/ choiceAxis, c $/ allAxis) of
304− ([], [], []) -> return Nothing
305− ([g], [], []) -> Just <$> parseSequence g
306− ([], [g], []) -> Just <$> parseChoice g
307− ([], [], [g]) -> Just <$> parseAll g
308− _ -> parseError c "Multiple model groups"
309−
310220parseSequence :: Cursor -> P Xsd.ModelGroup
311221parseSequence c = Xsd.Sequence <$> parseElements c
312222
@@ -317,45 +227,31 @@ parseAll :: Cursor -> P Xsd.ModelGroup
317227parseAll c = Xsd.All <$> parseElements c
318228
319229-- | Get all child elements
320−parseElements :: Cursor -> P [Xsd.RefOr Xsd.Element]
230+parseElements :: Cursor -> P [Xsd.Element]
321231parseElements c = do
322232 elementAxis <- makeElemAxis "element"
323− mapM parseElementOrRef (c $/ elementAxis)
324−
325−parseAttributes :: Cursor -> P [Xsd.Attribute]
326−parseAttributes c = do
327− attrAxis <- makeElemAxis "attribute"
328− mapM parseAttribute (c $/ attrAxis)
233+ mapM parseElement (c $/ elementAxis)
329234
330235parseAttribute :: Cursor -> P Xsd.Attribute
331236parseAttribute c = do
237+ name <- theAttribute "name" c >>= makeTargetQName
332238 use <- parseUseAttribute c
333− case (anAttribute "name" c, anAttribute "ref" c) of
334− (Just n, Nothing) -> do
335− name <- makeTargetQName n
336− tp <- case anAttribute "type" c of
337− Nothing -> do
338− simpleTypeAxis <- makeElemAxis "simpleType"
339− case c $/ simpleTypeAxis of
340− [s] -> Xsd.Inline <$> parseSimpleType s
341− [] -> return (Xsd.Ref anySimpleType)
342− _ -> parseError c "Multiple simple types"
343− Just t -> Xsd.Ref <$> makeQName c t
344− return $ Xsd.InlineAttribute $ Xsd.AttributeInline
345− { Xsd.attributeInlineName = name
346− , Xsd.attributeInlineUse = use
347− , Xsd.attributeInlineType = tp
348− }
349− (Nothing, Just r) -> do
350− ref <- makeQName c r
351− return $ Xsd.RefAttribute $ Xsd.AttributeRef
352− { Xsd.attributeRefRef = ref
353− , Xsd.attributeRefUse = use
354− }
355− _ -> parseError c "Should be either name or ref"
356− where
357− anySimpleType =
358− Xsd.QName (Just (Xsd.Namespace Xsd.schemaNamespace)) "anySimpleType"
239+
240+ -- XXX: generalaze RefOr parsing
241+ tp <- case anAttribute "type" c of
242+ Nothing -> do
243+ simpleTypeAxis <- makeElemAxis "simpleType"
244+ case c $/ simpleTypeAxis of
245+ [s] -> Xsd.Inline <$> parseSimpleType s
246+ [] -> parseError c "Attribute should have type"
247+ _ -> parseError c "Multiple simple types"
248+ Just t -> Xsd.Ref <$> makeQName c t
249+
250+ return Xsd.Attribute
251+ { Xsd.attrName = name
252+ , Xsd.attrUse = use
253+ , Xsd.attrType = tp
254+ }
359255
360256parseUseAttribute :: Cursor -> P Xsd.Use
361257parseUseAttribute c = case anAttribute "use" c of
@@ -511,9 +407,8 @@ makeElemAxis name = do
511407makeQName :: Cursor -> Text -> P Xsd.QName
512408makeQName c t = case Text.splitOn ":" t of
513409 [n] -> do
514− ns <- asks (lookup Nothing . envPrefixes)
515410 return Xsd.QName
516− { Xsd.qnNamespace = ns
411+ { Xsd.qnNamespace = Nothing
517412 , Xsd.qnName = n
518413 }
519414 [p, n] -> do
src/Xsd/Types.hs+17−87
@@ -6,23 +6,13 @@ module Xsd.Types
66, Child(..)
77, Type(..)
88, SimpleType(..)
9+, Restriction(..)
910, Constraint(..)
1011, ComplexType(..)
11−, Content(..)
12−, PlainContent(..)
13−, SimpleContent(..)
14−, SimpleExtension(..)
15−, SimpleRestriction(..)
16−, ComplexContent(..)
17−, ComplexExtension(..)
18−, ComplexRestriction(..)
1912, RefOr(..)
20−, refOr
2113, Element(..)
2214, MaxOccurs(..)
2315, Attribute(..)
24−, AttributeRef(..)
25−, AttributeInline(..)
2616, Annotation(..)
2717, Use(..)
2818, ModelGroup(..)
@@ -53,7 +43,7 @@ newtype Namespace = Namespace
5343 deriving (Show, Eq, Ord)
5444
5545data Child
56− = ChildElement (RefOr Element)
46+ = ChildElement Element
5747 | ChildType QName Type
5848 | ChildImport Import
5949 | ChildInclude Include
@@ -66,7 +56,6 @@ data Element = Element
6656 { elementName :: QName
6757 , elementType :: RefOr Type
6858 , elementOccurs :: (Int, MaxOccurs)
69− , elementNillable :: Bool
7059 , elementAnnotations :: [Annotation]
7160 }
7261 deriving (Show, Eq)
@@ -93,75 +82,28 @@ data Include = Include
9382 deriving (Show, Eq)
9483
9584data SimpleType
96− = AtomicType SimpleRestriction [Annotation]
85+ = AtomicType Restriction [Annotation]
9786 | ListType (RefOr SimpleType) [Annotation]
98− | UnionType [RefOr SimpleType] [Annotation]
87+ -- TODO: also union
9988 deriving (Show, Eq)
10089
10190data ComplexType = ComplexType
102− { complexAnnotations :: [Annotation]
103− , complexContent :: Content
91+ { complexAttributes :: [Attribute]
92+ , complexModelGroup :: Maybe ModelGroup
93+ , complexAnnotations :: [Annotation]
10494 }
10595 deriving (Show, Eq)
10696
107−data Content
108− = ContentComplex ComplexContent
109− | ContentSimple SimpleContent
110− | ContentPlain PlainContent
111− deriving (Show, Eq)
112−
113−-- | Represent content of complexType without simpleContent or complexContent
114−data PlainContent = PlainContent
115− { plainContentModel :: Maybe ModelGroup
116− , plainContentAttributes :: [Attribute]
117− }
118− deriving (Show, Eq)
119−
120−data ComplexContent
121− = ComplexContentExtension ComplexExtension
122− | ComplexContentRestriction ComplexRestriction
123− deriving (Show, Eq)
124−
125−data ComplexExtension = ComplexExtension
126− { complexExtensionBase :: QName
127− , complexExtensionModel :: Maybe ModelGroup
128− , complexExtensionAttributes :: [Attribute]
129− }
130− deriving (Show, Eq)
131−
132−data ComplexRestriction = ComplexRestriction
133− { complexRestrictionBase :: QName
134− , complexRestrictionModel :: Maybe ModelGroup
135− , complexRestrictionAttributes :: [Attribute]
136− }
137− deriving (Show, Eq)
138−
139−data SimpleContent
140− = SimpleContentExtension SimpleExtension
141− | SimpleContentRestriction SimpleRestriction
142− deriving (Show, Eq)
143−
14497data ModelGroup
145− = Sequence [RefOr Element]
146− | Choice [RefOr Element]
147− | All [RefOr Element]
148− deriving (Show, Eq)
149−
150−data Attribute
151− = RefAttribute AttributeRef
152− | InlineAttribute AttributeInline
153− deriving (Show, Eq)
154−
155−data AttributeInline = AttributeInline
156− { attributeInlineName :: QName
157− , attributeInlineType :: RefOr SimpleType
158− , attributeInlineUse :: Use
159− }
98+ = Sequence [Element]
99+ | Choice [Element]
100+ | All [Element]
160101 deriving (Show, Eq)
161102
162−data AttributeRef = AttributeRef
163− { attributeRefRef :: QName
164− , attributeRefUse :: Use
103+data Attribute = Attribute
104+ { attrName :: QName
105+ , attrType :: RefOr SimpleType
106+ , attrUse :: Use
165107 }
166108 deriving (Show, Eq)
167109
@@ -171,16 +113,9 @@ data Use
171113 | Required
172114 deriving (Show, Eq)
173115
174−data SimpleRestriction = SimpleRestriction
175− { simpleRestrictionBase :: RefOr SimpleType
176− -- XXX: could simpleRestrictionBase be an inline type? Probably not.
177− , simpleRestrictionConstraints :: [Constraint]
178− }
179− deriving (Show, Eq)
180−
181−data SimpleExtension = SimpleExtension
182− { simpleExtensionBase :: QName
183− , simpleExtensionAttributes :: [Attribute]
116+data Restriction = Restriction
117+ { restrictionBase :: RefOr SimpleType
118+ , restrictionConstraints :: [Constraint]
184119 }
185120 deriving (Show, Eq)
186121
@@ -190,11 +125,6 @@ data RefOr t
190125 | Inline t
191126 deriving (Show, Eq)
192127
193−refOr :: (QName -> a) -> (t -> a) -> RefOr t -> a
194−refOr f g ref = case ref of
195− Ref name -> f name
196− Inline t -> g t
197−
198128data Constraint
199129 = Enumeration Text
200130 deriving (Show, Eq)
test/Spec.hs+14−46
@@ -6,7 +6,6 @@ module Spec
66where
77
88import Data.Text (Text)
9−import Data.Maybe
109import Data.Either
1110import Data.Map (Map)
1211import qualified Data.Map as Map
@@ -91,7 +90,7 @@ spec = do
9190 Xsd.AtomicType restriction _ = t
9291 res `shouldSatisfy` isRight
9392 tpName `shouldBe` (Xsd.QName Nothing "str")
94− Xsd.simpleRestrictionBase restriction `shouldBe`
93+ Xsd.restrictionBase restriction `shouldBe`
9594 Xsd.Ref (Xsd.QName (Just (Xsd.Namespace "something")) "string")
9695
9796 context "when restriction contains enumerations" $ do
@@ -115,7 +114,7 @@ spec = do
115114 Xsd.AtomicType restriction _ = t
116115 res `shouldSatisfy` isRight
117116 tpName `shouldBe` (Xsd.QName Nothing "str")
118− Xsd.simpleRestrictionConstraints restriction `shouldBe`
117+ Xsd.restrictionConstraints restriction `shouldBe`
119118 [ Xsd.Enumeration "value1"
120119 , Xsd.Enumeration "value2"
121120 ]
@@ -138,10 +137,10 @@ spec = do
138137 fmap Xsd.children res
139138 Xsd.AtomicType restriction' _ = t
140139 Xsd.Inline (Xsd.AtomicType restriction _) =
141− Xsd.simpleRestrictionBase restriction'
140+ Xsd.restrictionBase restriction'
142141 res `shouldSatisfy` isRight
143142 tpName `shouldBe` (Xsd.QName Nothing "str")
144− Xsd.simpleRestrictionBase restriction `shouldBe`
143+ Xsd.restrictionBase restriction `shouldBe`
145144 Xsd.Ref (Xsd.QName (Just (Xsd.Namespace "something")) "string")
146145
147146 context "when base refers to an unbound prefix" $ do
@@ -199,12 +198,11 @@ spec = do
199198 res = Xsd.parse Xsd.defaultConfig doc
200199 Right [Xsd.ChildType tpName (Xsd.TypeComplex t)] =
201200 fmap Xsd.children res
202− Xsd.ContentPlain plain = Xsd.complexContent t
203− [Xsd.InlineAttribute attr] = Xsd.plainContentAttributes plain
201+ [attr] = Xsd.complexAttributes t
204202 res `shouldSatisfy` isRight
205203 tpName `shouldBe` Xsd.QName Nothing "person"
206− Xsd.attributeInlineName attr `shouldBe` Xsd.QName Nothing "firstName"
207− Xsd.attributeInlineType attr `shouldBe`
204+ Xsd.attrName attr `shouldBe` Xsd.QName Nothing "firstName"
205+ Xsd.attrType attr `shouldBe`
208206 Xsd.Ref (Xsd.QName (Just (Xsd.Namespace "something")) "string")
209207
210208 context "when attribute type is inlined" $ do
@@ -225,12 +223,10 @@ spec = do
225223 res = Xsd.parse Xsd.defaultConfig doc
226224 Right [Xsd.ChildType _ (Xsd.TypeComplex t)] =
227225 fmap Xsd.children res
228− Xsd.ContentPlain plain = Xsd.complexContent t
229− [Xsd.InlineAttribute attr] = Xsd.plainContentAttributes plain
230− Xsd.Inline (Xsd.AtomicType restriction _) =
231− Xsd.attributeInlineType attr
226+ [attr] = Xsd.complexAttributes t
227+ Xsd.Inline (Xsd.AtomicType restriction _) = Xsd.attrType attr
232228 res `shouldSatisfy` isRight
233− Xsd.simpleRestrictionBase restriction `shouldBe`
229+ Xsd.restrictionBase restriction `shouldBe`
234230 Xsd.Ref (Xsd.QName (Just (Xsd.Namespace "something")) "string")
235231
236232 context "when it contains a sequence" $ do
@@ -258,38 +254,10 @@ spec = do
258254 res = Xsd.parse Xsd.defaultConfig doc
259255 Right [Xsd.ChildType _ (Xsd.TypeComplex t)] =
260256 fmap Xsd.children res
261− Xsd.ContentPlain plain = Xsd.complexContent t
262− Just (Xsd.Sequence elems) = Xsd.plainContentModel plain
257+ Just (Xsd.Sequence elems) = Xsd.complexModelGroup t
263258 res `shouldSatisfy` isRight
264− mapMaybe (Xsd.refOr (const Nothing) (Just . Xsd.elementName)) elems
265− `shouldBe` map (Xsd.QName Nothing) ["firstName", "lastName"]
266−
267− context "when it contains complexContent" $ do
268− context "when it's an extenstion" $ do
269− it "succeeds" $ do
270− let
271− doc = mkDoc $
272− mkElem "schema"
273− (Map.fromList [("xmlns:xs","something")])
274− [NodeElement $ mkElem "complexType"
275− (Map.fromList [("name", "person")])
276− [NodeElement $ mkElem "complexContent" Map.empty
277− [ NodeElement $ mkElem "extension"
278− (Map.fromList [("base", "BaseType")])
279− [ NodeElement $ mkElem "sequence" Map.empty
280− [ NodeElement $ mkElem "element"
281− (Map.fromList
282− [ ("name", "first")
283− , ("type", "xs:string")])
284− []
285− ]]]]]
286− res = Xsd.parse Xsd.defaultConfig doc
287− Right [Xsd.ChildType _ (Xsd.TypeComplex t)] =
288− fmap Xsd.children res
289− Xsd.ContentComplex (Xsd.ComplexContentExtension e)
290− = Xsd.complexContent t
291− res `shouldSatisfy` isRight
292− Xsd.complexExtensionBase e `shouldBe` Xsd.QName Nothing "BaseType"
259+ map Xsd.elementName elems `shouldBe`
260+ map (Xsd.QName Nothing) ["firstName", "lastName"]
293261
294262 context "when element is given" $ do
295263 context "when type is inlined" $ do
@@ -307,7 +275,7 @@ spec = do
307275 ]
308276 ]
309277 res = Xsd.parse Xsd.defaultConfig doc
310− Right [Xsd.ChildElement (Xsd.Inline e)] = fmap Xsd.children res
278+ Right [Xsd.ChildElement e] = fmap Xsd.children res
311279 res `shouldSatisfy` isRight
312280 Xsd.elementName e `shouldBe`
313281 Xsd.QName Nothing "person"
xsd-parser.cabal+1−13
@@ -24,7 +24,7 @@ library
2424 , Xsd.Parser
2525
2626 -- Other library packages from which modules are imported.
27− build-depends: base >=4.12 && < 5
27+ build-depends: base ^>=4.12.0.0
2828 , bytestring
2929 , containers
3030 , lens >= 4.13
@@ -62,15 +62,3 @@ test-suite spec
6262 , xsd-parser
6363 default-language: Haskell2010
6464 ghc-options: -Wall
65−
66−test-suite xsts
67− type: exitcode-stdio-1.0
68− hs-source-dirs: xsts-test
69− main-is: Main.hs
70− build-depends: base
71− , text
72− , filepath
73− , xml-conduit
74− , xsd-parser
75− default-language: Haskell2010
76− ghc-options: -Wall
xsdtestsdeleted−1

Submodule changed.

xsts-test/Main.hsdeleted−201
@@ -1,201 +0,0 @@
1−{-# LANGUAGE OverloadedStrings #-}
2−
3−module Main
4−( main
5−)
6−where
7−
8−import Data.Text (Text)
9−import qualified Data.Text as Text
10−import Data.IORef
11−import Control.Monad
12−import Control.Exception
13−import System.FilePath
14−import System.IO.Unsafe (unsafePerformIO)
15−import qualified System.IO as IO
16−import Text.XML
17−import Text.XML.Cursor
18−
19−import qualified Xsd
20−
21−data Stat = Stat
22− { statTotal :: Int
23− , statSucceeded :: Int
24− , statValidFailed :: Int
25− , statInvalidSucceeded :: Int
26− }
27− deriving (Show)
28−
29−{-# NOINLINE errRef #-}
30−errRef :: IORef Int
31−errRef = unsafePerformIO (newIORef 0)
32−
33−{-# NOINLINE okRef #-}
34−okRef :: IORef Int
35−okRef = unsafePerformIO (newIORef 0)
36−
37−{-# NOINLINE statsRef #-}
38−statsRef :: IORef [(Text, Stat)]
39−statsRef = unsafePerformIO (newIORef [])
40−
41−dumpResults :: [(Text, Stat)] -> IO ()
42−dumpResults stats = IO.withFile "xsts.md" IO.WriteMode $ \h -> do
43− IO.hPutStrLn h "This table is generated automatically by `xsts` test."
44− IO.hPutStrLn h "It contains number of xsd files successfully parsed."
45− IO.hPutStrLn h "Note that we don't currently attempt to validate xml files"
46− IO.hPutStrLn h "against the schemata."
47− IO.hPutStrLn h ""
48− IO.hPutStrLn h "Test set | Total tests | Passed tests | Invalid passed | Valid failed"
49− IO.hPutStrLn h "--- | --- | --- | --- | ---"
50− forM_ stats $ \(name, s) -> do
51− IO.hPutStrLn h $ mconcat
52− [ Text.unpack name, " | "
53− , show (statTotal s), " | "
54− , show (statSucceeded s), " | "
55− , show (statInvalidSucceeded s), " | "
56− , show (statValidFailed s)
57− ]
58−
59−expectedFailures :: Int
60−expectedFailures = 3513
61−
62−main :: IO ()
63−main = do
64− let path = "./xsdtests/suite.xml"
65− doc <- Text.XML.readFile def path
66− runSuite path (fromDocument doc)
67− oks <- readIORef okRef
68− readIORef statsRef >>= dumpResults
69− putStrLn $ "Succeeded: " ++ show oks
70− errs <- readIORef errRef
71− putStrLn $ "Failed: " ++ show errs
72− unless (errs == expectedFailures) $
73− fail $ "There were " ++ show errs ++ " errors, expected "
74− ++ show expectedFailures
75−
76−runSuite :: FilePath -> Cursor -> IO ()
77−runSuite path c = mapM_ (runTestSetRef dir) (c $/ laxElement "testSetRef")
78− where
79− dir = takeDirectory path
80−
81−runTestSetRef :: FilePath -> Cursor -> IO ()
82−runTestSetRef dir c = do
83− ref <- theAttribute c "href"
84− let path = normalise (dir </> Text.unpack ref)
85− runTestSet path
86−
87−runTestSet :: FilePath -> IO ()
88−runTestSet path = do
89− doc <- Text.XML.readFile def path
90− let c = fromDocument doc
91− name <- theAttribute c "name"
92− putStrLn ("----- Test set " <> Text.unpack name)
93− results <- mapM (runTestGroup dir) (c $/ laxElement "testGroup")
94− let
95− stat = Stat
96− { statTotal = (sum . map statTotal) results
97− , statSucceeded = (sum . map statSucceeded) results
98− , statValidFailed = (sum . map statValidFailed) results
99− , statInvalidSucceeded = (sum . map statInvalidSucceeded) results
100− }
101− modifyIORef' statsRef ((name, stat) :)
102− where
103− dir = takeDirectory path
104−
105−runTestGroup :: FilePath -> Cursor -> IO Stat
106−runTestGroup dir c = do
107− name <- theAttribute c "name"
108− results <- mapM (runSchemaTest dir name) (aChild c "schemaTest")
109− case join results of
110− Nothing -> return Stat
111− { statTotal = 0
112− , statSucceeded = 0
113− , statValidFailed = 0
114− , statInvalidSucceeded = 0
115− }
116− Just ValidSucceeded -> return Stat
117− { statTotal = 1
118− , statSucceeded = 1
119− , statValidFailed = 0
120− , statInvalidSucceeded = 0
121− }
122− Just ValidFailed -> return Stat
123− { statTotal = 1
124− , statSucceeded = 0
125− , statValidFailed = 1
126− , statInvalidSucceeded = 0
127− }
128− Just InvalidSucceeded -> return Stat
129− { statTotal = 1
130− , statSucceeded = 0
131− , statValidFailed = 0
132− , statInvalidSucceeded = 1
133− }
134− Just InvalidFailed -> return Stat
135− { statTotal = 1
136− , statSucceeded = 1
137− , statValidFailed = 0
138− , statInvalidSucceeded = 0
139− }
140−
141−data Result
142− = InvalidFailed
143− | InvalidSucceeded
144− | ValidFailed
145− | ValidSucceeded
146− deriving (Show)
147−
148−runSchemaTest :: FilePath -> Text -> Cursor -> IO (Maybe Result)
149−runSchemaTest dir groupName c = do
150− path <- do
151− c' <- theChild c "schemaDocument"
152− theAttribute c' "href"
153− mvalid <- do
154− c' <- theChild c "expected"
155− valid <- theAttribute c' "validity"
156− case valid of
157− "valid" -> return (Just True)
158− "invalid" -> return (Just False)
159− _ -> return Nothing
160− case mvalid of
161− Nothing -> return Nothing -- indetermined
162− Just valid -> do
163− res <- try (Xsd.getSchema (dir </> Text.unpack path))
164− case (res, valid) of
165− (Left _, False) -> do
166− modifyIORef' okRef succ
167− return (Just InvalidFailed)
168− (Right _, True) -> do
169− modifyIORef' okRef succ
170− return (Just ValidSucceeded)
171− (Right _, False) -> do
172− modifyIORef' errRef succ
173− putStrLn $ "invalid xsd passed: " <> Text.unpack groupName
174− <> " (" <> dir </> Text.unpack path <> ")"
175− return (Just InvalidSucceeded)
176− (Left err, True) -> do
177− modifyIORef' errRef succ
178− putStrLn $ "valid xsd didn't pass: " <> Text.unpack groupName
179− <> " (" <> dir </> Text.unpack path <> ")"
180− <> ": " <> show (err :: SomeException)
181− return (Just ValidFailed)
182−
183−anAttribute :: Cursor -> Text -> Maybe Text
184−anAttribute c name = case c $| laxAttribute name of
185− (a:_) -> Just a
186− _ -> Nothing
187−
188−theAttribute :: Cursor -> Text -> IO Text
189−theAttribute c name = maybe err return (anAttribute c name)
190− where
191− err = fail $ "no attribute " <> Text.unpack name
192−
193−aChild :: Cursor -> Text -> Maybe Cursor
194−aChild c name = case c $/ laxElement name of
195− (a:_) -> Just a
196− _ -> Nothing
197−
198−theChild :: Cursor -> Text -> IO Cursor
199−theChild c name = case aChild c name of
200− Just a -> return a
201− _ -> fail $ "no element " <> Text.unpack name
xsts.mddeleted−100
@@ -1,100 +0,0 @@
1−This table is generated automatically by `xsts` test.
2−It contains number of xsd files successfully parsed.
3−Note that we don't currently attempt to validate xml files
4−against the schemata.
5−
6−Test set | Total tests | Passed tests | Invalid passed | Valid failed
7−--- | --- | --- | --- | ---
8−yearMonthDuration | 25 | 13 | 12 | 0
9−XSImportReference | 1 | 0 | 1 | 0
10−XPathDefaultNSonKeyKeyRefUnique | 13 | 13 | 0 | 0
11−XML11Support | 11 | 11 | 0 | 0
12−wildcard | 17 | 15 | 2 | 0
13−VC | 6 | 6 | 0 | 0
14−unsignedIntegers | 8 | 8 | 0 | 0
15−UnitsLength | 8 | 6 | 2 | 0
16−union | 19 | 14 | 5 | 0
17−CTA | 6 | 6 | 0 | 0
18−TypeAlternativeTests | 23 | 16 | 7 | 0
19−time | 1 | 1 | 0 | 0
20−TargetNS | 2 | 2 | 0 | 0
21−substitutionGroup | 5 | 3 | 2 | 0
22−rf-whiteSpace | 2 | 2 | 0 | 0
23−RestrictionOfComplexTypes | 13 | 9 | 4 | 0
24−RegularExpression | 8 | 8 | 0 | 0
25−PopenContent | 24 | 16 | 8 | 0
26−list | 2 | 1 | 1 | 0
27−IdentityConstraint | 12 | 6 | 6 | 0
28−ID_IDREF | 77 | 57 | 20 | 0
29−gMonth | 1 | 0 | 1 | 0
30−gDay | 1 | 1 | 0 | 0
31−gMonthDay | 1 | 1 | 0 | 0
32−gYear | 1 | 1 | 0 | 0
33−gYearMonth | 1 | 1 | 0 | 0
34−float | 2 | 2 | 0 | 0
35−explicitTimezone | 18 | 14 | 4 | 0
36−EDCWildcard | 2 | 2 | 0 | 0
37−double | 2 | 2 | 0 | 0
38−DefaultFixed | 5 | 5 | 0 | 0
39−defaultAttributesApply | 17 | 14 | 3 | 0
40−dayTimeDuration | 24 | 12 | 12 | 0
41−dateTimeStamp | 28 | 11 | 17 | 0
42−date | 1 | 1 | 0 | 0
43−CyclicDependencies_Redefine_Include_Import_Override | 5 | 0 | 5 | 0
44−constraintsOnAttribute | 16 | 6 | 10 | 0
45−ConditionalInclusion | 3 | 2 | 1 | 0
46−assertion | 51 | 50 | 1 | 0
47−Assert | 35 | 35 | 0 | 0
48−anyAttribute | 9 | 7 | 2 | 0
49−allGroup | 9 | 7 | 2 | 0
50−IRI | 1 | 1 | 0 | 0
51−substitution-groups | 6 | 6 | 0 | 0
52−Zone | 9 | 5 | 4 | 0
53−Zone | 20 | 15 | 5 | 0
54−XmlVersions | 13 | 13 | 0 | 0
55−Wild | 84 | 63 | 21 | 0
56−VC | 24 | 19 | 4 | 1
57−TargetNS | 4 | 2 | 2 | 0
58−Subsgroup | 6 | 3 | 3 | 0
59−Simple | 58 | 17 | 41 | 0
60−Override | 30 | 21 | 9 | 0
61−Open | 51 | 37 | 14 | 0
62−Missing | 6 | 4 | 2 | 0
63−Id | 32 | 30 | 2 | 0
64−CTA | 44 | 33 | 11 | 0
65−Complex | 25 | 19 | 6 | 0
66−Assert | 34 | 34 | 0 | 0
67−All | 62 | 26 | 34 | 2
68−BoeingXSDTestCases | 6 | 6 | 0 | 0
69−MS-Wildcards2006-07-15 | 315 | 218 | 97 | 0
70−MS-SimpleType2006-07-15 | 333 | 210 | 123 | 0
71−MS-Schema2006-07-15 | 124 | 56 | 61 | 7
72−MS-Regex2006-07-15 | 2590 | 1988 | 602 | 0
73−MS-Particles2006-07-15 | 855 | 561 | 293 | 1
74−MS-Notations2006-07-15 | 116 | 38 | 78 | 0
75−MS-ModelGroups2006-07-15 | 391 | 215 | 176 | 0
76−MS-IdentityConstraint2006-07-15 | 844 | 621 | 223 | 0
77−MS-Group2006-07-15 | 218 | 138 | 80 | 0
78−MS-Errata102006-07-15 | 19 | 15 | 4 | 0
79−MS-Element2006-07-15 | 355 | 263 | 92 | 0
80−MS-DataTypes2006-07-15 | 2247 | 1491 | 752 | 4
81−MS-ComplexType2006-07-15 | 550 | 311 | 239 | 0
82−MS-Attribute2006-07-15 | 279 | 165 | 114 | 0
83−MS-AttributeGroup2006-07-15 | 114 | 63 | 51 | 0
84−MS-Annotations2006-07-15 | 80 | 51 | 27 | 2
85−MS-Additional2006-07-15 | 253 | 202 | 45 | 6
86−Wildcard | 26 | 22 | 4 | 0
87−Schema | 6 | 6 | 0 | 0
88−SType | 138 | 131 | 7 | 0
89−Notation | 13 | 8 | 5 | 0
90−MGroupDef | 19 | 8 | 11 | 0
91−MGroup | 40 | 24 | 16 | 0
92−IdConstrDefs | 27 | 21 | 6 | 0
93−ElemDecl | 227 | 171 | 56 | 0
94−CType | 31 | 25 | 6 | 0
95−AttrUse | 4 | 3 | 1 | 0
96−AttrDecl | 83 | 78 | 5 | 0
97−AGroupDef | 13 | 6 | 7 | 0
98−suntest | 52 | 30 | 22 | 0
99−NIST2004-01-14 | 3953 | 3953 | 0 | 0
100−introspection | 1 | 0 | 0 | 1