git.iko.soy/typeable/xsd-parser
on master help sign in
17 files changed+1601−2744
since splitsnapshots
unifiedsplit
.gitmodules+3 README.md+10 src/Text/XSD.hs−10 src/Text/XSD/Internal.hs−197 src/Text/XSD/Parser.hs−197 src/Xsd.hs+144 src/Xsd/Parser.hs+579 src/Xsd/Types.hs+210 test/Main.hs+9 test/Spec.hs+319 test/fixtures/enhanced_air_ticket.xsd−1702 test/fixtures/retrieve_seat_map.xml−600 test/fixtures/simple.xsd−18 xsd-parser.cabal+25−20 xsdtests+1 xsts-test/Main.hs+201 xsts.md+100
.gitmodulesnew file+3
@@ -0,0 +1,3 @@
1+[submodule "xsdtests"]
2+ path = xsdtests
3+ url = git@github.com:w3c/xsdtests.git
README.mdnew file+10
@@ -0,0 +1,10 @@
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/Text/XSD.hsdeleted−10
@@ -1,10 +0,0 @@
1−{-# LANGUAGE TemplateHaskell #-}
2−
3−-- | A subset of XSD specification.
4−module Text.XSD
5− ( module Text.XSD.Internal
6− , module Text.XSD.Parser
7− ) where
8−
9−import Text.XSD.Internal
10−import Text.XSD.Parser
src/Text/XSD/Internal.hsdeleted−197
@@ -1,197 +0,0 @@
1−{-# LANGUAGE OverloadedStrings #-}
2−{-# LANGUAGE TemplateHaskell #-}
3−
4−-- | A subset of XSD specification.
5−module Text.XSD.Internal where
6−
7−import Control.Exception
8−import Control.Lens
9−import Data.Text as T
10−import Data.Map as M
11−
12−
13−-- | Roughly based on https://www.w3.org/TR/xmlschema11-2/#built-in-datatypes
14−-- | and https://www.w3.org/TR/xmlschema11-1/#dcl.ctd.ctsc
15−data Datatype
16− = TypeComplex ComplexType
17− | TypeSimple SimpleType
18− deriving (Show, Eq)
19−
20−data ComplexType
21− = ComplexType (Maybe Text) [Attribute] [Annotation] (Maybe ModelGroupSchema)
22− deriving (Show, Eq)
23−
24−data Attribute = Attribute Text SimpleType UseProp
25− deriving (Show, Eq)
26−
27−data UseProp
28− = Optional -- this is the default if missing in xsd
29− | Prohibited
30− | Required
31− deriving (Show, Eq)
32−
33−fromUsePropStr :: Text -> Maybe UseProp
34−fromUsePropStr "optional" = Just $ Optional
35−fromUsePropStr "required" = Just $ Required
36−fromUsePropStr "prohibited" = Just $ Prohibited
37−fromUsePropStr _ = Nothing
38−
39−data Annotation
40− = Documentation Text
41− deriving (Show, Eq)
42−
43−data DatatypeRef
44− = InlineComplex Datatype
45− | DatatypeRef Text
46− deriving (Show, Eq)
47−
48−-- | Based on https://www.w3.org/TR/2012/REC-xmlschema11-1-20120405/structures.html#Model_Group_details
49−data ModelGroupSchema
50− = CTSequence [Element]
51− | CTChoice [Element]
52− | CTAll [Element]
53− deriving (Show, Eq)
54−
55−fromSimpleTypeStr :: QName -> Either String SimpleAtomicType
56−fromSimpleTypeStr (_, "anyURI") = Right $ STAnyURI
57−fromSimpleTypeStr (_, "base64Binary") = Right $ STBase64Binary
58−fromSimpleTypeStr (_, "boolean") = Right $ STBoolean
59−fromSimpleTypeStr (_, "date") = Right $ STDate
60−fromSimpleTypeStr (_, "datetime") = Right $ STDateTime
61−fromSimpleTypeStr (_, "dateTimeStamp") = Right $ STDateTimeStamp
62−fromSimpleTypeStr (_, "decimal") = Right $ STDecimal DTDecimal
63−fromSimpleTypeStr (_, "integer") = Right $ STDecimal DTInteger
64−fromSimpleTypeStr (_, "long") = Right $ STDecimal DTLong
65−fromSimpleTypeStr (_, "int") = Right $ STDecimal DTInt
66−fromSimpleTypeStr (_, "short") = Right $ STDecimal DTShort
67−fromSimpleTypeStr (_, "byte") = Right $ STDecimal DTByte
68−fromSimpleTypeStr (_, "nonNegativeInteger")= Right $ STDecimal DTNonNegativeInteger
69−fromSimpleTypeStr (_, "positiveInteger") = Right $ STDecimal DTPositiveInteger
70−fromSimpleTypeStr (_, "unsignedLong") = Right $ STDecimal DTUnsignedLong
71−fromSimpleTypeStr (_, "unsignedInt") = Right $ STDecimal DTUnsignedInt
72−fromSimpleTypeStr (_, "unsignedShort") = Right $ STDecimal DTUnsignedShort
73−fromSimpleTypeStr (_, "unsignedByte") = Right $ STDecimal DTUnsignedByte
74−fromSimpleTypeStr (_, "nonPositiveInteger")= Right $ STDecimal DTNonPositiveInteger
75−fromSimpleTypeStr (_, "negativeInteger") = Right $ STDecimal DTNegativeInteger
76−fromSimpleTypeStr (_, "float") = Right $ STFloat
77−fromSimpleTypeStr (_, "gDay") = Right $ STGDay
78−fromSimpleTypeStr (_, "gMonth") = Right $ STGMonth
79−fromSimpleTypeStr (_, "gMonthDay") = Right $ STGMonthDay
80−fromSimpleTypeStr (_, "gYear") = Right $ STGYear
81−fromSimpleTypeStr (_, "gYearMonth") = Right $ STGYearMonth
82−fromSimpleTypeStr (_, "hexBinary") = Right $ STHexBinary
83−fromSimpleTypeStr (_, "NOTATION") = Right $ STNOTATION
84−fromSimpleTypeStr (_, "QName") = Right $ STQName
85−fromSimpleTypeStr (_, "string") = Right $ STString StrString
86−fromSimpleTypeStr (_, "normalizedString") = Right $ STString StrNormalizedString
87−fromSimpleTypeStr (_, "token") = Right $ STString StrToken
88−fromSimpleTypeStr (_, "language") = Right $ STString StrLanguage
89−fromSimpleTypeStr (_, "Name") = Right $ STString StrName
90−fromSimpleTypeStr (_, "NCName") = Right $ STString StrNCName
91−fromSimpleTypeStr (_, "ENTITY") = Right $ STString StrENTITY
92−fromSimpleTypeStr (_, "ID") = Right $ STString StrID
93−fromSimpleTypeStr (_, "IDREF") = Right $ STString StrIDREF
94−fromSimpleTypeStr (_, "NMTOKEN") = Right $ STString StrNMTOKEN
95−fromSimpleTypeStr (_, "time") = Right $ STTime
96−fromSimpleTypeStr (_, t) = Left $ "unsupported type: " <> T.unpack t
97−
98−-- | ENTITIES, IDREFS and NMTOKENS are not supported right now.
99−data SimpleType
100− = STAtomic Text SimpleAtomicType [Annotation] [Restriction]
101− -- STUnion [SimpleType] -- special - xs:union
102− -- STList [SimpleType] -- special - xs:list
103− deriving (Show, Eq)
104−
105−data Restriction
106− = Enumeration [Text]
107− deriving (Show, Eq)
108−
109−data SimpleAtomicType
110− = STAnyURI
111− | STBase64Binary
112− | STBoolean
113− | STDate
114− | STDateTime
115− | STDateTimeStamp
116− | STDecimal DecimalType
117− | STDouble
118− | STDuration DurationType
119− | STFloat
120− | STGDay
121− | STGMonth
122− | STGMonthDay
123− | STGYear
124− | STGYearMonth
125− | STHexBinary
126− | STNOTATION
127− | STQName
128− | STString StringType
129− | STTime
130− deriving (Show, Eq)
131−
132−data StringType
133− = StrString
134− | StrNormalizedString
135− | StrToken
136− | StrLanguage
137− | StrName
138− | StrNCName
139− | StrENTITY
140− | StrID
141− | StrIDREF
142− | StrNMTOKEN
143− deriving (Show, Eq)
144−
145−data DurationType = DayTimeDuration | YearMonthDuration deriving (Show, Eq)
146−
147−data DecimalType
148− = DTDecimal
149− | DTInteger
150− | DTLong
151− | DTInt
152− | DTShort
153− | DTByte
154− | DTNonNegativeInteger
155− | DTPositiveInteger
156− | DTUnsignedLong
157− | DTUnsignedInt
158− | DTUnsignedShort
159− | DTUnsignedByte
160− | DTNonPositiveInteger
161− | DTNegativeInteger
162− deriving (Show, Eq)
163−
164−type LocalName = Text
165−
166−type Namespace = Text
167−
168−type QName = (Maybe Namespace, LocalName)
169−
170−toQName :: Text -> QName
171−toQName n =
172− let splitName@(f:l) = T.split (==':') n
173− in if Prelude.length splitName == 1
174− then (Nothing, f)
175− else (Just f, Prelude.head l)
176−
177−-- | Based on https://www.w3.org/TR/xmlschema11-1/#concepts-data-model
178−-- Secondary and helper schema components are not supported right now.
179−-- data SchemaComponent
180−-- = SCDatatype Datatype
181−-- | SCElement Element
182−-- | SCAttribute
183−-- deriving (Show)
184−
185−data Element = Element
186− { name :: !QName
187− , xtype :: !DatatypeRef
188− , minOccurs :: Int
189− , maxOccurs :: (Maybe Int)
190− , annotations :: [Annotation]
191− } deriving (Show, Eq)
192−
193−type DatatypeMap = M.Map Text Datatype
194−
195−-- | Embodies an XSD document
196−newtype XSD = XSD { unXSD :: ([Element], DatatypeMap) }
197− deriving (Show, Eq)
src/Text/XSD/Parser.hsdeleted−197
@@ -1,197 +0,0 @@
1−{-# LANGUAGE LambdaCase #-}
2−{-# LANGUAGE OverloadedStrings #-}
3−
4−module Text.XSD.Parser where
5−
6−import Control.Exception
7−import Control.Monad
8−import Control.Monad.Except (throwError)
9−import Control.Monad.Trans.Reader
10−import Control.Monad.Writer.CPS
11−import Data.ByteString.Lazy
12−import Data.Foldable as F
13−-- import Data.Generics.Uniplate.Operations
14−import Data.Map as M
15−import Debug.Trace
16−import Data.Maybe
17−import Data.Text as T
18−import Prelude as P
19−import Text.XML as XML
20−import Text.XML.Cursor as XML
21−import Text.XSD.Internal as XSD
22−
23−
24−newtype XSDException = XSDException String
25− deriving (Show)
26−
27−instance Exception XSDException
28−
29−type XSDMonad a = WriterT DatatypeMap (Either SomeException) a
30−
31−parseXSD :: ParseSettings -> ByteString -> Either SomeException XSD
32−parseXSD ps bs = parseLBS ps bs >>= toXsd
33−
34−-- Show is Meh
35−throwXsd :: Show s => s -> XSDMonad a
36−throwXsd = throwError . SomeException . XSDException . show
37−
38−maybeThrowXsd :: Show s => Maybe a -> s -> XSDMonad a
39−maybeThrowXsd (Just a) _ = pure a
40−maybeThrowXsd Nothing e = throwXsd e
41−
42−attrThrowXsd :: Show s => XML.Name -> XML.Element -> s -> XSDMonad Text
43−attrThrowXsd name elNode = maybeThrowXsd (M.lookup name $ elementAttributes elNode)
44−
45−-- | Tells the writer about named complex types and returns a list of elements.
46−toElemsAndDatatypes :: XML.Cursor -> XSDMonad [XSD.Element]
47−toElemsAndDatatypes cursor = do
48− elems <- traverse toElem (cursor $/ laxElement "element")
49− complexDatatypes <- traverse toComplexType (cursor $/ laxElement "complexType")
50− for_ complexDatatypes $ \case
51− datatype@(ComplexType (Just name) _ _ _) ->
52− tell (M.singleton name (TypeComplex datatype))
53− datatype@(ComplexType Nothing _ _ _) ->
54− throwXsd $ "unnamed type ref for datatype: " <> show datatype
55− simpleTypes <- traverse toSimpleType (cursor $/ laxElement "simpleType")
56− for_ simpleTypes $ \simpleType@(STAtomic name _ _ _) ->
57− tell (M.singleton name (TypeSimple simpleType))
58− pure elems
59−
60−safeHead :: [a] -> Maybe a
61−safeHead [] = Nothing
62−safeHead (a:_) = Just a
63−
64−getDocumentation :: Cursor -> [Annotation]
65−getDocumentation cursor = Documentation <$> documentation
66− where
67− documentation = cursor
68− $/ laxElement "annotation"
69− &// laxElement "documentation"
70− &/ content
71−
72−-- | Takes a cursor to the element itself.
73−toElem :: Cursor -> XSDMonad XSD.Element
74−toElem cursor = do
75− case node cursor of
76− NodeElement el -> case nameLocalName (elementName el) of
77− "element" -> do
78− let
79− attrs = elementAttributes el
80− mAttrType = M.lookup "type" attrs
81− ns = nameNamespace $ elementName el
82− name <- attrThrowXsd "name" el
83− $ "Expected attribute 'name' for element: " <> show (node cursor)
84− let
85− minOc = maybe 0 (read . T.unpack) (M.lookup "minOccurs" attrs)
86− maxOc = read . T.unpack <$> M.lookup "maxOccurs" attrs
87− datatypeRef <- case mAttrType of
88− Just dtn -> pure $ DatatypeRef dtn
89− Nothing -> do
90− let complexType = cursor $// laxElement "complexType"
91− if P.null complexType
92− then throwXsd $ "No datatype definition found for element: " <> name
93− else do
94− childCursor <- maybeThrowXsd (safeHead complexType)
95− $ "More than one xs:complexType tag in: " <> show cursor
96− let name = safeHead $ childCursor $| attribute "name"
97− InlineComplex . TypeComplex <$> toComplexType childCursor
98− pure $ XSD.Element
99− { name = (ns, name)
100− , xtype = datatypeRef
101− , minOccurs = minOc
102− , maxOccurs = maxOc
103− , annotations = getDocumentation cursor }
104− e -> throwXsd $ "[toElem] xsd node not supported: " <> show e
105− e ->
106− throwXsd $ "[toElem] element expected, got: " <> show e
107−
108−toSimpleType :: Cursor -> XSDMonad SimpleType
109−toSimpleType cursor = do
110− name <- maybeThrowXsd
111− (safeHead $ cursor $| attribute "name")
112− $ "More than one \"name\" attribute in simpleType declaration"
113− let restrictionAxis = laxElement "restriction"
114− if P.null (cursor $// restrictionAxis)
115− then throwXsd $ "unsupported simpleType element: " <> show cursor
116− else do
117− childCursor <- maybeThrowXsd (safeHead $ cursor $// restrictionAxis)
118− $ "Unexpected number of <restriction> tags in: " <> show cursor
119− baseType <- maybeThrowXsd (safeHead $ childCursor $| attribute "base")
120− $ "No base attribute provided for restriction tag in: " <> show cursor
121− let
122− enumValues = childCursor $// laxElement "enumeration" &/ attribute "value"
123− -- only enumeration is supported now
124− case fromSimpleTypeStr $ toQName baseType of
125− Left e -> throwXsd e
126− Right simpleAtomicType ->
127− pure $ STAtomic name simpleAtomicType
128− (getDocumentation cursor)
129− $ if P.null enumValues then [] else [Enumeration enumValues]
130−
131−-- | Takes a cursor to the 'xs:complexType' element.
132−toComplexType :: Cursor -> XSDMonad ComplexType
133−toComplexType cursor = do
134− let attributeAxis = laxElement "attribute"
135− let sequenceAxis = laxElement "sequence"
136− let choiceAxis = laxElement "choice"
137− let allAxis = laxElement "all"
138− -- attributes
139− attrs <- traverse toAttribute (cursor $// attributeAxis)
140− let ann = getDocumentation cursor
141− -- group model schemas
142− if P.null (cursor $// sequenceAxis)
143− then if P.null (cursor $// choiceAxis)
144− then if P.null (cursor $// allAxis)
145− then throwXsd $ "No definition found for complexType: "
146− <> show (safeHead $ cursor $// laxElement "complexType")
147− else do
148− childCursor <- maybeThrowXsd (safeHead $ cursor $// allAxis)
149− $ "Unexpected number of xs:all tags in: " <> show cursor
150− let
151− name = safeHead $ cursor $| attribute "name"
152− ComplexType name attrs ann . Just . CTAll <$> toElemsAndDatatypes childCursor
153− else do
154− childCursor <- maybeThrowXsd (safeHead $ cursor $// choiceAxis)
155− $ "Unexpected number of xs:choice tags in: " <> show cursor
156− let
157− name = safeHead $ cursor $| attribute "name"
158− ComplexType name attrs ann . Just . CTChoice <$> toElemsAndDatatypes childCursor
159− else do
160− childCursor <- maybeThrowXsd (safeHead $ cursor $// sequenceAxis)
161− $ "Unexpected number of xs:sequence tags in: " <> show cursor
162− let
163− name = safeHead $ cursor $| attribute "name"
164− ComplexType name attrs ann . Just . CTSequence <$> toElemsAndDatatypes childCursor
165−
166−toAttribute :: XML.Cursor -> XSDMonad Attribute
167−toAttribute cursor = do
168− name <- maybeThrowXsd (safeHead $ cursor $| attribute "name")
169− $ "No name attribute found in child <attribute> of: "
170− <> show (cursor $| ancestor <=< ancestor)
171− let ann = getDocumentation cursor
172− simpleType <- case safeHead $ cursor $| attribute "type" of
173− Just simpleAtomicType ->
174− case fromSimpleTypeStr $ toQName simpleAtomicType of
175− Left e -> throwXsd e
176− Right simpleAtomicType -> pure $ STAtomic name simpleAtomicType ann []
177− Nothing -> do
178− let simpleTypeCursor = safeHead $ cursor $// laxElement "simpleType"
179− case simpleTypeCursor of
180− Just st -> toSimpleType cursor
181− Nothing -> throwXsd
182− $ "No type attribute found in child <attribute> of: "
183− <> show (cursor $| ancestor <=< ancestor)
184− let
185− useProp = case fromUsePropStr =<< safeHead (cursor $| attribute "use") of
186− Just up -> up
187− Nothing -> Optional
188− pure $ Attribute name simpleType useProp
189−
190−toXsd :: Document -> Either SomeException XSD
191−toXsd doc = do
192− let cursor = fromDocument doc
193− XSD <$> (runWriterT $ do
194− let topLevel = cursor $| laxElement "schema"
195− if P.null topLevel
196− then throwXsd "Top-level schema definition not found"
197− else toElemsAndDatatypes cursor)
src/Xsd.hsnew file+144
@@ -0,0 +1,144 @@
1+
2+module Xsd
3+( module Xsd.Types
4+, module Xsd.Parser
5+, Schema(..)
6+, getSchema
7+, mergeSchemata
8+)
9+where
10+
11+import qualified Data.Text as Text
12+import Data.Maybe
13+import Data.Map (Map)
14+import qualified Data.Map as Map
15+import qualified Data.Set as Set
16+import Control.Monad.IO.Class
17+import Control.Monad.Trans.State
18+import Network.URI (URI)
19+import qualified Network.URI as URI
20+import qualified Network.HTTP.Client as Http
21+import qualified Network.HTTP.Client.TLS as Http
22+import System.FilePath
23+
24+import Xsd.Types
25+import Xsd.Parser
26+
27+data Schema = Schema
28+ { schemaTypes :: Map QName Type
29+ , schemaElements :: Map QName Element
30+ }
31+ deriving (Show)
32+
33+emptySchema :: Schema
34+emptySchema = Schema
35+ { schemaTypes = Map.empty
36+ , schemaElements = Map.empty
37+ }
38+
39+mergeSchemata :: Schema -> Schema -> Schema
40+mergeSchemata s1 s2 = Schema
41+ { schemaTypes = schemaTypes s1 <> schemaTypes s2
42+ , schemaElements = schemaElements s1 <> schemaElements s2
43+ }
44+
45+instance Semigroup Schema where
46+ (<>) = mergeSchemata
47+
48+instance Monoid Schema where
49+ mempty = emptySchema
50+
51+-- | Get schema from file or URL
52+getSchema :: String -> IO Schema
53+getSchema source = do
54+ uri <- maybe (fail "Can't parse the source URI") return
55+ (URI.parseURIReference source)
56+ mconcat <$> evalStateT (go uri []) Set.empty
57+ where
58+ go uri schemata = do
59+ skip <- gets (Set.member uri)
60+ if skip
61+ then return schemata
62+ else do
63+ xsd <- liftIO $ fetchXsd uri
64+ modify' (Set.insert uri)
65+ let
66+ schema = xsdToSchema xsd
67+ includes = flip mapMaybe (children xsd) $ \c -> case c of
68+ ChildInclude i -> Just i
69+ _ -> Nothing
70+ imports = flip mapMaybe (children xsd) $ \c -> case c of
71+ ChildImport i -> Just i
72+ _ -> Nothing
73+ goInclude uri includes (schema:schemata)
74+ >>= goImports uri imports
75+
76+ goInclude _ [] schemata = return schemata
77+ goInclude uri (i:is) schemata = do
78+ let location = includeLocation i
79+ uri' <- maybe
80+ (fail ("Can't parse the location URI " <> show location))
81+ (\u -> return $ combineURIs uri u )
82+ (URI.parseURIReference (Text.unpack location))
83+ go uri' schemata
84+ >>= goInclude uri is
85+
86+ goImports _ [] schemata = return schemata
87+ goImports uri (i:is) schemata =
88+ case importLocation i of
89+ Nothing -> goImports uri is schemata
90+ Just location -> do
91+ uri' <- maybe
92+ (fail ("Can't parse the location URI " <> show location))
93+ (\u -> return $ combineURIs uri u)
94+ (URI.parseURIReference (Text.unpack location))
95+ go uri' schemata
96+ >>= goImports uri is
97+
98+-- | If the second URI is relative, then make it relative to the first one
99+combineURIs :: URI -> URI -> URI
100+combineURIs u1 u2 = if URI.uriIsAbsolute u2
101+ then u2
102+ else if isLocal u1
103+ then u1 {URI.uriPath = dropFileName (URI.uriPath u1) </> URI.uriPath u2}
104+ else u2 `URI.relativeTo` u1
105+
106+xsdToSchema :: Xsd -> Schema
107+xsdToSchema xsd = Schema
108+ { schemaTypes = Map.fromList types
109+ , schemaElements = Map.fromList elements
110+ }
111+ where
112+ (types, elements) = go ([], []) (children xsd)
113+ go res [] = res
114+ go (ts, es) (c:cs) = case c of
115+ ChildType n t -> go ((n, t):ts, es) cs
116+ ChildElement (Inline e) -> go (ts, (elementName e, e):es) cs
117+ _ -> go (ts, es) cs
118+
119+fetchXsd :: URI -> IO Xsd
120+fetchXsd uri = do
121+ let
122+ path = URI.uriToString id uri ""
123+ onParseErr e = fail $ path ++ ": " ++ show e
124+ if isLocal uri
125+ then
126+ parseFile path
127+ >>= either onParseErr return
128+ else fetchHttp path
129+
130+fetchHttp :: String -> IO Xsd
131+fetchHttp url = do
132+ mgr <- Http.newTlsManager
133+ req <- Http.parseUrlThrow url
134+ resp <- Http.responseBody <$> Http.httpLbs req mgr
135+ either onErr return $
136+ parseLazyByteString resp
137+ where
138+ onErr e = fail $ url ++ ": " ++ show e
139+
140+isLocal :: URI -> Bool
141+isLocal uri = case URI.uriScheme uri of
142+ "http:" -> False
143+ "https:" -> False
144+ _ -> True
src/Xsd/Parser.hsnew file+579
@@ -0,0 +1,579 @@
1+{-# LANGUAGE OverloadedStrings #-}
2+
3+module Xsd.Parser
4+( parse
5+, parseFile
6+, parseLazyByteString
7+, ParseError(..)
8+, Config(..)
9+, defaultConfig
10+)
11+where
12+
13+import qualified Data.ByteString.Lazy as Lazy (ByteString)
14+import Data.Text (Text)
15+import qualified Data.Text as Text
16+import Data.Maybe
17+import qualified Data.Map as Map
18+import Control.Monad
19+import Control.Monad.Trans
20+import Control.Monad.Trans.Reader
21+import Control.Monad.Trans.Except
22+import Text.Read (readEither)
23+import Text.XML
24+import Text.XML.Cursor
25+
26+import Xsd.Types (Xsd(Xsd))
27+import qualified Xsd.Types as Xsd
28+
29+parseSchema :: Cursor -> P Xsd
30+parseSchema c = do
31+ let targetNamespace = Xsd.Namespace <$> anAttribute "targetNamespace" c
32+
33+ children <- local (\env -> env {envTargetNamespace = targetNamespace}) $
34+ parseChildren c
35+ return Xsd
36+ { Xsd.targetNamespace = targetNamespace
37+ , Xsd.children = children
38+ }
39+
40+parseChildren :: Cursor -> P [Xsd.Child]
41+parseChildren c =
42+ catMaybes <$> mapM parseChild (c $/ anyElement)
43+
44+-- | Parse top level schema node
45+--
46+-- Returns Nothing for unknown/unsupported nodes
47+parseChild :: Cursor -> P (Maybe Xsd.Child)
48+parseChild c = do
49+ name <- getElementName c
50+ case name of
51+ "element" -> Just . Xsd.ChildElement <$> parseElementOrRef c
52+ "simpleType" -> Just <$> parseTopSimpleType c
53+ "complexType" -> Just <$> parseTopComplexType c
54+ "include" -> Just . Xsd.ChildInclude <$> parseInclude c
55+ "import" -> Just . Xsd.ChildImport <$> parseImport c
56+ _ -> return Nothing
57+
58+parseInclude :: Cursor -> P Xsd.Include
59+parseInclude c = do
60+ location <- theAttribute "schemaLocation" c
61+ return Xsd.Include
62+ { Xsd.includeLocation = location
63+ }
64+
65+parseImport :: Cursor -> P Xsd.Import
66+parseImport c = do
67+ let
68+ location = anAttribute "schemaLocation" c
69+ namespace = Xsd.Namespace <$> anAttribute "namespace" c
70+
71+ tns <- asks envTargetNamespace
72+ case (namespace, tns) of
73+ (Nothing, Nothing) -> parseError c "Expected namespace"
74+ (Just ns1, Just ns2)
75+ | ns1 == ns2
76+ -> parseError c "Namespace equals target namespace"
77+ _ -> return ()
78+
79+ return Xsd.Import
80+ { Xsd.importLocation = location
81+ , Xsd.importNamespace = namespace
82+ }
83+
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+
90+parseElement :: Cursor -> P Xsd.Element
91+parseElement c = handleNamespaces c $ do
92+ name <- theAttribute "name" c
93+
94+ tp <- case anAttribute "type" c of
95+ Just t -> Xsd.Ref <$> makeQName c t
96+ _ -> maybe (Xsd.Ref anyType) Xsd.Inline <$> parseType c
97+
98+ minOccurs <- case anAttribute "minOccurs" c of
99+ Nothing -> return 1
100+ Just val -> case readEither (Text.unpack val) of
101+ Left err -> parseError c ("Can't parse minOccurs: " <> Text.pack err)
102+ Right v -> return v
103+
104+ maxOccurs <- case anAttribute "maxOccurs" c of
105+ Nothing -> return (Xsd.MaxOccurs 1)
106+ Just "unbounded" -> return Xsd.MaxOccursUnbound
107+ Just val -> case readEither (Text.unpack val) of
108+ Left err -> parseError c ("Can't parse maxOccurs" <> Text.pack err)
109+ Right v -> return (Xsd.MaxOccurs v)
110+
111+ annotations <- parseAnnotations c
112+
113+ qname <- makeTargetQName name
114+
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+
121+ return Xsd.Element
122+ { Xsd.elementName = qname
123+ , Xsd.elementType = tp
124+ , Xsd.elementAnnotations = annotations
125+ , Xsd.elementOccurs = (minOccurs, maxOccurs)
126+ , Xsd.elementNillable = nillable
127+ }
128+ where
129+ anyType = Xsd.QName (Just (Xsd.Namespace Xsd.schemaNamespace)) "anyType"
130+
131+-- | Parse inline type, simple or complex
132+parseType :: Cursor -> P (Maybe Xsd.Type)
133+parseType c = do
134+ simpleTypeAxis <- makeElemAxis "simpleType"
135+ complexTypeAxis <- makeElemAxis "complexType"
136+ case (c $/ simpleTypeAxis, c $/ complexTypeAxis) of
137+ ([], []) -> return Nothing
138+ ([t], []) -> Just . Xsd.TypeSimple <$> parseSimpleType t
139+ ([], [t]) -> Just . Xsd.TypeComplex <$> parseComplexType t
140+ _ -> parseError c "Multiple types"
141+
142+-- | Top level simple type
143+parseTopSimpleType :: Cursor -> P Xsd.Child
144+parseTopSimpleType c = do
145+ name <- theAttribute "name" c >>= makeTargetQName
146+ t <- parseSimpleType c
147+ return $ Xsd.ChildType name (Xsd.TypeSimple t)
148+
149+-- | Top level complex type
150+parseTopComplexType :: Cursor -> P Xsd.Child
151+parseTopComplexType c = do
152+ name <- theAttribute "name" c >>= makeTargetQName
153+ t <- parseComplexType c
154+ return $ Xsd.ChildType name (Xsd.TypeComplex t)
155+
156+parseSimpleType :: Cursor -> P Xsd.SimpleType
157+parseSimpleType c = do
158+ restrictionAxis <- makeElemAxis "restriction"
159+ listAxis <- makeElemAxis "list"
160+ unionAxis <- makeElemAxis "union"
161+ case (c $/ restrictionAxis, c $/ listAxis, c $/ unionAxis) of
162+ ([e], [], []) -> Xsd.AtomicType
163+ <$> parseSimpleRestriction e
164+ <*> parseAnnotations c
165+ ([], [l], []) -> Xsd.ListType
166+ <$> parseList l
167+ <*> parseAnnotations c
168+ ([], [], [u]) -> Xsd.UnionType
169+ <$> parseUnion u
170+ <*> parseAnnotations c
171+ _ -> parseError c "Expected exactly of of restriction, list or union"
172+
173+-- | Restriction for simple type
174+parseSimpleRestriction :: Cursor -> P Xsd.SimpleRestriction
175+parseSimpleRestriction c = do
176+ -- XXX: generalaze RefOr parsing
177+ tp <- case anAttribute "base" c of
178+ Nothing -> do
179+ simpleTypeAxis <- makeElemAxis "simpleType"
180+ case c $/ simpleTypeAxis of
181+ [] -> parseError c "Expected simpleType"
182+ [s] -> Xsd.Inline <$> parseSimpleType s
183+ _ -> parseError c "Multiple types"
184+ Just t -> Xsd.Ref <$> makeQName c t
185+
186+ constraints <- parseConstrains c
187+
188+ return Xsd.SimpleRestriction
189+ { Xsd.simpleRestrictionBase = tp
190+ , Xsd.simpleRestrictionConstraints = constraints
191+ }
192+
193+parseConstrains :: Cursor -> P [Xsd.Constraint]
194+parseConstrains c = do
195+ enumerationAxis <- makeElemAxis "enumeration"
196+ forM (c $/ enumerationAxis) $ \e -> do
197+ Xsd.Enumeration <$> theAttribute "value" e
198+
199+parseList :: Cursor -> P (Xsd.RefOr Xsd.SimpleType)
200+parseList c =
201+ -- XXX: generalaze RefOr parsing
202+ case anAttribute "itemType" c of
203+ Nothing -> do
204+ simpleTypeAxis <- makeElemAxis "simpleType"
205+ case c $/ simpleTypeAxis of
206+ [] -> parseError c "Expected simpleType"
207+ [s] -> Xsd.Inline <$> parseSimpleType s
208+ _ -> parseError c "Multiple types"
209+ Just t -> Xsd.Ref <$> makeQName c t
210+
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+
220+parseComplexType :: Cursor -> P Xsd.ComplexType
221+parseComplexType 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+ }
266+
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+ }
286+
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
296+ }
297+
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+
310+parseSequence :: Cursor -> P Xsd.ModelGroup
311+parseSequence c = Xsd.Sequence <$> parseElements c
312+
313+parseChoice :: Cursor -> P Xsd.ModelGroup
314+parseChoice c = Xsd.Choice <$> parseElements c
315+
316+parseAll :: Cursor -> P Xsd.ModelGroup
317+parseAll c = Xsd.All <$> parseElements c
318+
319+-- | Get all child elements
320+parseElements :: Cursor -> P [Xsd.RefOr Xsd.Element]
321+parseElements c = do
322+ 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)
329+
330+parseAttribute :: Cursor -> P Xsd.Attribute
331+parseAttribute c = do
332+ 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"
359+
360+parseUseAttribute :: Cursor -> P Xsd.Use
361+parseUseAttribute c = case anAttribute "use" c of
362+ Nothing -> return Xsd.Optional
363+ Just "optional" -> return Xsd.Optional
364+ Just "required" -> return Xsd.Required
365+ Just "prohibited" -> return Xsd.Prohibited
366+ _ -> parseError c "Unknown attribute use"
367+
368+parseAnnotations :: Cursor -> P [Xsd.Annotation]
369+parseAnnotations c = do
370+ annotationAxis <- makeElemAxis "annotation"
371+ documentationAxis <- makeElemAxis "documentation"
372+
373+ let
374+ documentation = c
375+ $/ annotationAxis
376+ &// documentationAxis
377+ &/ content
378+ return $ Xsd.Documentation <$> documentation
379+
380+-- Section: parser entry points
381+
382+-- | Specifies modes of operation
383+data Config = Config
384+ { configIgnoreSchemaNamespace :: Bool
385+ -- ^ if not set, parser will check that all relevant xml nodes
386+ -- live is the correct XMLSchema namespace
387+ }
388+ deriving (Show)
389+
390+-- | Default configuration
391+defaultConfig :: Config
392+defaultConfig = Config
393+ { configIgnoreSchemaNamespace = False
394+ }
395+
396+-- | Parse the whole document
397+--
398+-- Make sure the document is parsed with `psRetainNamespaces` enabled!
399+parse :: Config -> Document -> Either ParseError Xsd
400+parse conf doc = do
401+ let
402+ env = Env
403+ { envConfig = conf
404+ , envTargetNamespace = Nothing
405+ , envPrefixes = []
406+ }
407+ c = fromDocument doc
408+ runExcept $ flip runReaderT env $ handleNamespaces c $ do
409+ schemaAxis <- makeElemAxis "schema"
410+ case c $.// schemaAxis of
411+ [] -> parseError c "Not schema found"
412+ [s] -> parseSchema s
413+ _ -> parseError c "Multiple schemata found"
414+
415+-- | Parse file
416+--
417+-- It uses the `defaultConfig`
418+parseFile :: FilePath -> IO (Either ParseError Xsd)
419+parseFile path = parse defaultConfig <$>
420+ Text.XML.readFile def{psRetainNamespaces=True} path
421+
422+parseLazyByteString :: Lazy.ByteString -> Either ParseError Xsd
423+parseLazyByteString = parse defaultConfig
424+ . parseLBS_ def{psRetainNamespaces=True}
425+
426+-- Section: parser environment
427+
428+-- | Namespace prefix, e.g. \"xs\" or \"tns\"
429+newtype Prefix = Prefix Text
430+ deriving (Show, Eq)
431+
432+-- | Parser environment
433+data Env = Env
434+ { envConfig :: Config
435+ , envTargetNamespace :: Maybe Xsd.Namespace
436+ -- ^ targetNamespace for the current schema
437+ , envPrefixes :: [(Maybe Prefix, Xsd.Namespace)]
438+ -- ^ all xmlns:prefix="namespace" things from the
439+ -- schema element
440+ }
441+ deriving (Show)
442+
443+-- | Parser
444+type P a = ReaderT Env (Except ParseError) a
445+
446+-- Section: error handling
447+
448+-- | Describes what exactly went wrong
449+data ParseError = ParseError
450+ { errorLocation :: Text
451+ -- ^ e.g. schema.element[Person].attribute[firstName]
452+ , errorMessage :: Text
453+ }
454+ deriving (Show)
455+
456+-- | Builds path to the current curson position
457+--
458+-- Goes through parents and collects their element names,
459+-- optionally adds value of "name" attribute
460+pprCursor :: Cursor -> Text
461+pprCursor = Text.intercalate "." . go []
462+ where
463+ go ctx c = case node c of
464+ NodeElement e ->
465+ let
466+ ctx' = name : ctx
467+ elemName = nameLocalName (elementName e)
468+ name = case laxAttribute "name" c of
469+ (n:_) -> elemName <> "[" <> n <> "]"
470+ _ -> elemName
471+ in case parent c of
472+ (p:_) -> go ctx' p
473+ _ -> ctx'
474+ _ -> ctx
475+
476+-- | Fail with the location and message
477+parseError :: Cursor -> Text -> P a
478+parseError c msg = lift $ throwE ParseError
479+ { errorLocation = pprCursor c
480+ , errorMessage = msg
481+ }
482+
483+-- Section: general utilities
484+
485+-- | Get value of an optional attribute
486+anAttribute :: Text -> Cursor -> Maybe Text
487+anAttribute name c = case c $| laxAttribute name of
488+ (a:_) -> Just a
489+ _ -> Nothing
490+
491+-- | Get value of the required attribute
492+theAttribute :: Text -> Cursor -> P Text
493+theAttribute name c = maybe err return (anAttribute name c)
494+ where
495+ err = parseError c ("Element should have attibute " <> name)
496+
497+-- | Select nodes with the specified name
498+--
499+-- Depending on the `configIgnoreSchemaNamespace`, it will or will not
500+-- check the namespace to be XMLSchema one
501+makeElemAxis :: Text -> P Axis
502+makeElemAxis name = do
503+ ignore <- asks (configIgnoreSchemaNamespace . envConfig)
504+ return $ if ignore
505+ then laxElement name
506+ else element (mkSchemaName name)
507+
508+-- | Parses reference to a type
509+--
510+-- Fails if it has a prefix which is not bound
511+makeQName :: Cursor -> Text -> P Xsd.QName
512+makeQName c t = case Text.splitOn ":" t of
513+ [n] -> do
514+ ns <- asks (lookup Nothing . envPrefixes)
515+ return Xsd.QName
516+ { Xsd.qnNamespace = ns
517+ , Xsd.qnName = n
518+ }
519+ [p, n] -> do
520+ known <- asks (lookup (Just (Prefix p)) . envPrefixes)
521+ case known of
522+ Nothing -> parseError c "Unbound prefix"
523+ _ -> return ()
524+ return Xsd.QName
525+ { Xsd.qnNamespace = known
526+ , Xsd.qnName = n
527+ }
528+ _ -> parseError c ("Can't parse name " <> t)
529+
530+makeTargetQName :: Text -> P Xsd.QName
531+makeTargetQName name = do
532+ tns <- asks envTargetNamespace
533+ return Xsd.QName
534+ { Xsd.qnNamespace = tns
535+ , Xsd.qnName = name
536+ }
537+
538+-- | Get name of the current node
539+--
540+-- Depending on `configIgnoreSchemaNamespace` value, it will or will not
541+-- check the namespace to be XMLSchema one
542+getElementName :: Cursor -> P Text
543+getElementName c = do
544+ case node c of
545+ NodeElement e -> do
546+ let name = elementName e
547+ ignore <- asks (configIgnoreSchemaNamespace . envConfig)
548+ unless ignore $ do
549+ when (nameNamespace name /= Just Xsd.schemaNamespace) $ do
550+ parseError c "Expected XMLSchema element"
551+ return (nameLocalName name)
552+ _ -> parseError c "Expected node element here"
553+
554+-- | Attaches xml schema namespace
555+mkSchemaName :: Text -> Name
556+mkSchemaName name = Name name (Just Xsd.schemaNamespace) Nothing
557+
558+-- | Add additional xmlns bindings into local scope
559+handleNamespaces :: Cursor -> P a -> P a
560+handleNamespaces c m = do
561+ ns <- parsePrefixes c
562+ local (\env -> env {envPrefixes = ns ++ envPrefixes env}) m
563+
564+-- | Parse namespace bindings
565+--
566+-- Cursor should point to schema node
567+parsePrefixes :: Cursor -> P [(Maybe Prefix, Xsd.Namespace)]
568+parsePrefixes c = case node c of
569+ NodeElement e -> return
570+ . concatMap toPrefix
571+ . Map.toList
572+ . elementAttributes
573+ $ e
574+ _ -> parseError c "Expected an element"
575+ where
576+ toPrefix (n, v) = case Text.splitOn ":" (nameLocalName n) of
577+ ["xmlns"] -> [(Nothing, Xsd.Namespace v)]
578+ ["xmlns", prefix] -> [(Just (Prefix prefix), Xsd.Namespace v)]
579+ _ -> []
src/Xsd/Types.hsnew file+210
@@ -0,0 +1,210 @@
1+{-# LANGUAGE OverloadedStrings #-}
2+
3+module Xsd.Types
4+( Xsd(..)
5+, Namespace(..)
6+, Child(..)
7+, Type(..)
8+, SimpleType(..)
9+, Constraint(..)
10+, ComplexType(..)
11+, Content(..)
12+, PlainContent(..)
13+, SimpleContent(..)
14+, SimpleExtension(..)
15+, SimpleRestriction(..)
16+, ComplexContent(..)
17+, ComplexExtension(..)
18+, ComplexRestriction(..)
19+, RefOr(..)
20+, refOr
21+, Element(..)
22+, MaxOccurs(..)
23+, Attribute(..)
24+, AttributeRef(..)
25+, AttributeInline(..)
26+, Annotation(..)
27+, Use(..)
28+, ModelGroup(..)
29+, Import(..)
30+, Include(..)
31+, QName(..)
32+, schemaNamespace
33+)
34+where
35+
36+import Data.Text (Text)
37+
38+data Xsd = Xsd
39+ { targetNamespace :: Maybe Namespace
40+ , children :: [Child]
41+ -- XXX: Investigate whether there could be any dependency on the order
42+ -- on children. E.g whether an element can reference type from other
43+ -- namespace only after the namespace is imported.
44+ -- If there is no such dependency, then get rid of Child and list
45+ -- types and elements separately here.
46+ }
47+ deriving (Show, Eq)
48+
49+-- | Namespace name, e.g. \"http://www.w3.org/2001/XMLSchema\"
50+newtype Namespace = Namespace
51+ { fromNamespace :: Text
52+ }
53+ deriving (Show, Eq, Ord)
54+
55+data Child
56+ = ChildElement (RefOr Element)
57+ | ChildType QName Type
58+ | ChildImport Import
59+ | ChildInclude Include
60+ deriving (Show, Eq)
61+
62+data Annotation = Documentation Text
63+ deriving (Show, Eq)
64+
65+data Element = Element
66+ { elementName :: QName
67+ , elementType :: RefOr Type
68+ , elementOccurs :: (Int, MaxOccurs)
69+ , elementNillable :: Bool
70+ , elementAnnotations :: [Annotation]
71+ }
72+ deriving (Show, Eq)
73+
74+data MaxOccurs
75+ = MaxOccurs Int
76+ | MaxOccursUnbound
77+ deriving (Show, Eq)
78+
79+data Type
80+ = TypeSimple SimpleType
81+ | TypeComplex ComplexType
82+ deriving (Show, Eq)
83+
84+data Import = Import
85+ { importNamespace :: Maybe Namespace
86+ , importLocation :: Maybe Text
87+ }
88+ deriving (Show, Eq)
89+
90+data Include = Include
91+ { includeLocation :: Text
92+ }
93+ deriving (Show, Eq)
94+
95+data SimpleType
96+ = AtomicType SimpleRestriction [Annotation]
97+ | ListType (RefOr SimpleType) [Annotation]
98+ | UnionType [RefOr SimpleType] [Annotation]
99+ deriving (Show, Eq)
100+
101+data ComplexType = ComplexType
102+ { complexAnnotations :: [Annotation]
103+ , complexContent :: Content
104+ }
105+ deriving (Show, Eq)
106+
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+
144+data 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+ }
160+ deriving (Show, Eq)
161+
162+data AttributeRef = AttributeRef
163+ { attributeRefRef :: QName
164+ , attributeRefUse :: Use
165+ }
166+ deriving (Show, Eq)
167+
168+data Use
169+ = Optional
170+ | Prohibited
171+ | Required
172+ deriving (Show, Eq)
173+
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]
184+ }
185+ deriving (Show, Eq)
186+
187+-- | Reference to a type or an inline one
188+data RefOr t
189+ = Ref QName
190+ | Inline t
191+ deriving (Show, Eq)
192+
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+
198+data Constraint
199+ = Enumeration Text
200+ deriving (Show, Eq)
201+
202+data QName = QName
203+ { qnNamespace :: Maybe Namespace
204+ , qnName :: Text
205+ }
206+ deriving (Show, Eq, Ord)
207+
208+-- | XMLSchema namespace, all relevant xml nodes should live in it
209+schemaNamespace :: Text
210+schemaNamespace = "http://www.w3.org/2001/XMLSchema"
test/Main.hsnew file+9
@@ -0,0 +1,9 @@
1+module Main where
2+
3+import Test.Hspec
4+
5+import Spec (spec)
6+
7+main :: IO ()
8+main = hspec $ do
9+ spec
test/Spec.hsnew file+319
@@ -0,0 +1,319 @@
1+{-# LANGUAGE OverloadedStrings #-}
2+
3+module Spec
4+( spec
5+)
6+where
7+
8+import Data.Text (Text)
9+import Data.Maybe
10+import Data.Either
11+import Data.Map (Map)
12+import qualified Data.Map as Map
13+import Text.XML
14+
15+import qualified Xsd
16+
17+import Test.Hspec
18+
19+spec :: Spec
20+spec = do
21+ describe "parse" $ do
22+ context "when targetNamespace is given" $ do
23+ it "parses the namespace" $ do
24+ let
25+ doc = mkDoc $
26+ mkElem "schema"
27+ (Map.fromList[("targetNamespace", "something")])
28+ []
29+ Right xsd = Xsd.parse Xsd.defaultConfig doc
30+ Xsd.targetNamespace xsd `shouldBe` Just (Xsd.Namespace "something")
31+
32+ context "when targetNamespace is not given" $ do
33+ it "returns Nothing" $ do
34+ let
35+ doc = mkDoc $
36+ mkElem "schema"
37+ (Map.fromList [])
38+ []
39+ Right xsd = Xsd.parse Xsd.defaultConfig doc
40+ Xsd.targetNamespace xsd `shouldBe` Nothing
41+
42+ context "when root element is not schema" $ do
43+ context "when root element has different name" $ do
44+ it "fails" $ do
45+ let
46+ doc = mkDoc $
47+ mkElem "notschema"
48+ (Map.fromList [])
49+ []
50+ Left err = Xsd.parse Xsd.defaultConfig doc
51+ Xsd.errorLocation err `shouldBe` "notschema"
52+
53+ context "when root element has different namespace" $ do
54+ it "fails" $ do
55+ let
56+ doc = mkDoc $
57+ Element "{othernamespace}schema"
58+ (Map.fromList [])
59+ []
60+ Left err = Xsd.parse Xsd.defaultConfig doc
61+ Xsd.errorLocation err `shouldBe` "schema"
62+
63+ context "when ignoring schema namespace" $ do
64+ it "succeeds" $ do
65+ let
66+ doc = mkDoc $
67+ Element "{othernamespace}schema"
68+ (Map.fromList [])
69+ []
70+ res = Xsd.parse conf doc
71+ conf = Xsd.defaultConfig
72+ { Xsd.configIgnoreSchemaNamespace = True
73+ }
74+ res `shouldSatisfy` isRight
75+
76+ context "when simple type is given" $ do
77+ context "when it's atomic with restriction" $ do
78+ it "parses it" $ do
79+ let
80+ doc = mkDoc $
81+ mkElem "schema"
82+ (Map.fromList [("xmlns:xs","something")])
83+ [NodeElement $ mkElem "simpleType"
84+ (Map.fromList [("name", "str")])
85+ [NodeElement $ mkElem "restriction"
86+ (Map.fromList [("base", "xs:string")])
87+ []]]
88+ res = Xsd.parse Xsd.defaultConfig doc
89+ Right [Xsd.ChildType tpName (Xsd.TypeSimple t)] =
90+ fmap Xsd.children res
91+ Xsd.AtomicType restriction _ = t
92+ res `shouldSatisfy` isRight
93+ tpName `shouldBe` (Xsd.QName Nothing "str")
94+ Xsd.simpleRestrictionBase restriction `shouldBe`
95+ Xsd.Ref (Xsd.QName (Just (Xsd.Namespace "something")) "string")
96+
97+ context "when restriction contains enumerations" $ do
98+ it "parses them" $ do
99+ let
100+ doc = mkDoc $
101+ mkElem "schema"
102+ (Map.fromList [("xmlns:xs","something")])
103+ [NodeElement $ mkElem "simpleType"
104+ (Map.fromList [("name", "str")])
105+ [NodeElement $ mkElem "restriction"
106+ (Map.fromList [("base", "xs:string")])
107+ [ NodeElement $ mkElem "enumeration"
108+ (Map.fromList [("value", "value1")]) []
109+ , NodeElement $ mkElem "enumeration"
110+ (Map.fromList [("value", "value2")]) []
111+ ]]]
112+ res = Xsd.parse Xsd.defaultConfig doc
113+ Right [Xsd.ChildType tpName (Xsd.TypeSimple t)] =
114+ fmap Xsd.children res
115+ Xsd.AtomicType restriction _ = t
116+ res `shouldSatisfy` isRight
117+ tpName `shouldBe` (Xsd.QName Nothing "str")
118+ Xsd.simpleRestrictionConstraints restriction `shouldBe`
119+ [ Xsd.Enumeration "value1"
120+ , Xsd.Enumeration "value2"
121+ ]
122+
123+ context "when restrication base is inlined" $ do
124+ it "parses it" $ do
125+ let
126+ doc = mkDoc $
127+ mkElem "schema"
128+ (Map.fromList [("xmlns:xs","something")])
129+ [NodeElement $ mkElem "simpleType"
130+ (Map.fromList [("name", "str")])
131+ [NodeElement $ mkElem "restriction" Map.empty
132+ [NodeElement $ mkElem "simpleType" Map.empty
133+ [NodeElement $ mkElem "restriction"
134+ (Map.fromList [("base", "xs:string")])
135+ []]]]]
136+ res = Xsd.parse Xsd.defaultConfig doc
137+ Right [Xsd.ChildType tpName (Xsd.TypeSimple t)] =
138+ fmap Xsd.children res
139+ Xsd.AtomicType restriction' _ = t
140+ Xsd.Inline (Xsd.AtomicType restriction _) =
141+ Xsd.simpleRestrictionBase restriction'
142+ res `shouldSatisfy` isRight
143+ tpName `shouldBe` (Xsd.QName Nothing "str")
144+ Xsd.simpleRestrictionBase restriction `shouldBe`
145+ Xsd.Ref (Xsd.QName (Just (Xsd.Namespace "something")) "string")
146+
147+ context "when base refers to an unbound prefix" $ do
148+ it "fails" $ do
149+ let
150+ doc = mkDoc $
151+ mkElem "schema"
152+ (Map.fromList [])
153+ [NodeElement $ mkElem "simpleType"
154+ (Map.fromList [("name", "str")])
155+ [NodeElement $ mkElem "restriction"
156+ (Map.fromList [("base", "xs:string")])
157+ []]]
158+ res = Xsd.parse Xsd.defaultConfig doc
159+ Left err = res
160+ res `shouldSatisfy` isLeft
161+ Xsd.errorLocation err `shouldBe`
162+ "schema.simpleType[str].restriction"
163+
164+ context "when target namespace is provided" $ do
165+ it "parses it" $ do
166+ let
167+ doc = mkDoc $
168+ mkElem "schema"
169+ (Map.fromList
170+ [ ("xmlns:xs","something")
171+ , ("targetNamespace", "me")
172+ ])
173+ [NodeElement $ mkElem "simpleType"
174+ (Map.fromList [("name", "str")])
175+ [NodeElement $ mkElem "restriction"
176+ (Map.fromList [("base", "xs:string")])
177+ []]]
178+ res = Xsd.parse Xsd.defaultConfig doc
179+ Right [Xsd.ChildType tpName _] = fmap Xsd.children res
180+ res `shouldSatisfy` isRight
181+ tpName `shouldBe` (Xsd.QName (Just (Xsd.Namespace "me")) "str")
182+
183+ context "when complex type is given" $ do
184+ context "when it has attributes" $ do
185+ context "when attribute type is a reference" $ do
186+ it "succeeds" $ do
187+ let
188+ doc = mkDoc $
189+ mkElem "schema"
190+ (Map.fromList [("xmlns:xs","something")])
191+ [NodeElement $ mkElem "complexType"
192+ (Map.fromList [("name", "person")])
193+ [NodeElement $ mkElem "attribute"
194+ (Map.fromList
195+ [ ("type", "xs:string")
196+ , ("name", "firstName")
197+ ])
198+ []]]
199+ res = Xsd.parse Xsd.defaultConfig doc
200+ Right [Xsd.ChildType tpName (Xsd.TypeComplex t)] =
201+ fmap Xsd.children res
202+ Xsd.ContentPlain plain = Xsd.complexContent t
203+ [Xsd.InlineAttribute attr] = Xsd.plainContentAttributes plain
204+ res `shouldSatisfy` isRight
205+ tpName `shouldBe` Xsd.QName Nothing "person"
206+ Xsd.attributeInlineName attr `shouldBe` Xsd.QName Nothing "firstName"
207+ Xsd.attributeInlineType attr `shouldBe`
208+ Xsd.Ref (Xsd.QName (Just (Xsd.Namespace "something")) "string")
209+
210+ context "when attribute type is inlined" $ do
211+ it "succeeds" $ do
212+ let
213+ doc = mkDoc $
214+ mkElem "schema"
215+ (Map.fromList [("xmlns:xs","something")])
216+ [NodeElement $ mkElem "complexType"
217+ (Map.fromList [("name", "person")])
218+ [NodeElement $ mkElem "attribute"
219+ (Map.fromList [("name", "firstName")])
220+ [NodeElement $ mkElem "simpleType"
221+ (Map.empty)
222+ [NodeElement $ mkElem "restriction"
223+ (Map.fromList [("base", "xs:string")])
224+ []]]]]
225+ res = Xsd.parse Xsd.defaultConfig doc
226+ Right [Xsd.ChildType _ (Xsd.TypeComplex t)] =
227+ 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
232+ res `shouldSatisfy` isRight
233+ Xsd.simpleRestrictionBase restriction `shouldBe`
234+ Xsd.Ref (Xsd.QName (Just (Xsd.Namespace "something")) "string")
235+
236+ context "when it contains a sequence" $ do
237+ it "succeeds" $ do
238+ let
239+ doc = mkDoc $
240+ mkElem "schema"
241+ (Map.fromList [("xmlns:xs","something")])
242+ [NodeElement $ mkElem "complexType"
243+ (Map.fromList [("name", "person")])
244+ [NodeElement $ mkElem "sequence" Map.empty
245+ [ NodeElement $ mkElem "element"
246+ (Map.fromList
247+ [ ("name", "firstName")
248+ , ("type", "xs:string")
249+ ])
250+ []
251+ , NodeElement $ mkElem "element"
252+ (Map.fromList
253+ [ ("name", "lastName")
254+ , ("type", "xs:string")
255+ ])
256+ []
257+ ]]]
258+ res = Xsd.parse Xsd.defaultConfig doc
259+ Right [Xsd.ChildType _ (Xsd.TypeComplex t)] =
260+ fmap Xsd.children res
261+ Xsd.ContentPlain plain = Xsd.complexContent t
262+ Just (Xsd.Sequence elems) = Xsd.plainContentModel plain
263+ 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"
293+
294+ context "when element is given" $ do
295+ context "when type is inlined" $ do
296+ it "succeeds" $ do
297+ let
298+ doc = mkDoc $
299+ mkElem "schema"
300+ (Map.fromList [("xmlns:xs","something")])
301+ [NodeElement $ mkElem "element"
302+ (Map.fromList [("name", "person")])
303+ [NodeElement $ mkElem "simpleType" Map.empty
304+ [NodeElement $ mkElem "restriction"
305+ (Map.fromList [("base", "xs:string")])
306+ []]
307+ ]
308+ ]
309+ res = Xsd.parse Xsd.defaultConfig doc
310+ Right [Xsd.ChildElement (Xsd.Inline e)] = fmap Xsd.children res
311+ res `shouldSatisfy` isRight
312+ Xsd.elementName e `shouldBe`
313+ Xsd.QName Nothing "person"
314+
315+mkDoc :: Element -> Document
316+mkDoc e = Document (Prologue [] Nothing []) e []
317+
318+mkElem :: Text -> Map Name Text -> [Node] -> Element
319+mkElem n = Element (Name n (Just Xsd.schemaNamespace) Nothing)
test/fixtures/enhanced_air_ticket.xsddeleted−1702
@@ -1,1702 +0,0 @@
1−<schema xmlns="http://www.w3.org/2001/XMLSchema" xmlns:spct="http://services.sabre.com/sp/common/simple/v3" xmlns:stlp="http://services.sabre.com/STL_Payload/v02_01" xmlns:ns1="http://services.sabre.com/sp/air/ticket/v1" targetNamespace="http://services.sabre.com/sp/air/ticket/v1" elementFormDefault="qualified">
2− <import namespace="http://services.sabre.com/STL_Payload/v02_01" schemaLocation="built-ins/STL2_Payload_v02_01.xsd"/>
3− <import namespace="http://services.sabre.com/sp/common/simple/v3" schemaLocation="SpCommonSimpleTypes_v3.xsd"/>
4− <element name="AirTicketRQ">
5− <complexType>
6− <complexContent>
7− <extension base="stlp:STL_Request_Payload">
8− <sequence>
9− <element name="DesignatePrinter" minOccurs="0">
10− <complexType>
11− <sequence>
12− <element name="Printers" minOccurs="0">
13− <complexType>
14− <sequence>
15− <element name="BagTag" minOccurs="0">
16− <complexType>
17− <attribute name="LNIATA" type="string" use="optional">
18− <annotation>
19− <documentation>"LNIATA" is used to specify a bag tag printer address.</documentation>
20− </annotation>
21− </attribute>
22− </complexType>
23− </element>
24− <element name="BoardingPass" minOccurs="0">
25− <complexType>
26− <attribute name="HostedCarrier" type="boolean" use="optional">
27− <annotation>
28− <documentation>"HostedCarrier" is used by airline customers to indicate that this request is for an airline-based boarding pass printer.</documentation>
29− </annotation>
30− </attribute>
31− <attribute name="LNIATA" type="string" use="optional">
32− <annotation>
33− <documentation>"LNIATA" is used to specify a bag tag printer address.</documentation>
34− </annotation>
35− </attribute>
36− </complexType>
37− </element>
38− <element name="Hardcopy" minOccurs="0">
39− <complexType>
40− <attribute name="Spacing" use="optional">
41− <annotation>
42− <documentation>"Spacing" is used to specify the spacing, either 1, or 2.</documentation>
43− </annotation>
44− <simpleType>
45− <restriction base="string">
46− <enumeration value="1"/>
47− <enumeration value="2"/>
48− </restriction>
49− </simpleType>
50− </attribute>
51− <attribute name="LNIATA" type="string" use="optional">
52− <annotation>
53− <documentation>"LNIATA" is used to specify a bag tag printer address.</documentation>
54− </annotation>
55− </attribute>
56− </complexType>
57− </element>
58− <element name="InvoiceItinerary" minOccurs="0">
59− <complexType>
60− <attribute name="LNIATA" type="string" use="optional">
61− <annotation>
62− <documentation>"LNIATA" is used to specify a bag tag printer address.</documentation>
63− </annotation>
64− </attribute>
65− </complexType>
66− </element>
67− <element name="ListLabel" minOccurs="0">
68− <complexType>
69− <attribute name="LNIATA" type="string" use="optional">
70− <annotation>
71− <documentation>"LNIATA" is used to specify a bag tag printer address.</documentation>
72− </annotation>
73− </attribute>
74− </complexType>
75− </element>
76− <element name="MiniItinerary" minOccurs="0">
77− <complexType>
78− <attribute name="LNIATA" type="string" use="optional">
79− <annotation>
80− <documentation>"LNIATA" is used to specify a bag tag printer address.</documentation>
81− </annotation>
82− </attribute>
83− </complexType>
84− </element>
85− <element name="Report" minOccurs="0">
86− <complexType>
87− <attribute name="LNIATA" type="string" use="optional">
88− <annotation>
89− <documentation>"LNIATA" is used to specify a bag tag printer address.</documentation>
90− </annotation>
91− </attribute>
92− </complexType>
93− </element>
94− <element name="Ticket" minOccurs="0">
95− <complexType>
96− <sequence>
97− <element name="MiniItinerary" minOccurs="0">
98− <complexType>
99− <attribute name="LNIATA" type="string" use="optional">
100− <annotation>
101− <documentation>"LNIATA" is used to specify a bag tag printer address.</documentation>
102− </annotation>
103− </attribute>
104− </complexType>
105− </element>
106− <element name="Remote" minOccurs="0">
107− <complexType>
108− <attribute name="LNIATA" type="string" use="optional">
109− <annotation>
110− <documentation>"LNIATA" is used to specify a bag tag printer address.</documentation>
111− </annotation>
112− </attribute>
113− </complexType>
114− </element>
115− </sequence>
116− <attribute name="CountryCode" type="string" use="optional"/>
117− <attribute name="LNIATA" type="string" use="optional">
118− <annotation>
119− <documentation>"LNIATA" is used to specify a bag tag printer address.</documentation>
120− </annotation>
121− </attribute>
122− </complexType>
123− </element>
124− </sequence>
125− </complexType>
126− </element>
127− <element name="Profile" minOccurs="0">
128− <complexType>
129− <attribute name="Number" type="integer" use="optional">
130− <annotation>
131− <documentation>"Number" is used to specify a previously established printer number.</documentation>
132− </annotation>
133− </attribute>
134− </complexType>
135− </element>
136− </sequence>
137− </complexType>
138− </element>
139− <element name="Itinerary" minOccurs="1">
140− <complexType>
141− <attribute name="ID" use="required">
142− <annotation>
143− <documentation>"ID" is used to specify a record locator.</documentation>
144− </annotation>
145− <simpleType>
146− <restriction base="string"/>
147− </simpleType>
148− </attribute>
149− </complexType>
150− </element>
151− <element name="AccountingLines" minOccurs="0">
152− <complexType>
153− <sequence>
154− <element name="Delete" minOccurs="0" maxOccurs="unbounded">
155− <complexType>
156− <attribute name="EndNumber" type="integer" use="optional">
157− <annotation>
158− <documentation>"EndNumber" when used with @Number to specify a range of accounting lines to delete.</documentation>
159− </annotation>
160− </attribute>
161− <attribute name="Number" type="integer" use="required">
162− <annotation>
163− <documentation>"Number" is used to specify particular accounting lines.</documentation>
164− </annotation>
165− </attribute>
166− </complexType>
167− </element>
168− </sequence>
169− <attribute name="All" type="boolean" use="optional">
170− <annotation>
171− <documentation>"All" is used to delete all accounting lines, cannot combine with attribute None.</documentation>
172− </annotation>
173− </attribute>
174− <attribute name="None" type="boolean" use="optional">
175− <annotation>
176− <documentation>"None" is used to indicate not to delete any of the accounting lines, cannot combine with "All" attribute.</documentation>
177− </annotation>
178− </attribute>
179− </complexType>
180− </element>
181− <element name="Ticketing" minOccurs="1" maxOccurs="99">
182− <complexType>
183− <sequence>
184− <element name="FlightQualifiers" minOccurs="0">
185− <complexType>
186− <sequence>
187− <element name="VendorPrefs" minOccurs="0">
188− <complexType>
189− <sequence>
190− <element name="Airline">
191− <complexType>
192− <attribute name="Code" type="string" use="required">
193− <annotation>
194− <documentation>"Code" is used to specify a particular vendor code.</documentation>
195− </annotation>
196− </attribute>
197− </complexType>
198− </element>
199− </sequence>
200− </complexType>
201− </element>
202− </sequence>
203− </complexType>
204− </element>
205− <element name="FOP_Qualifiers" minOccurs="0">
206− <complexType>
207− <sequence>
208− <element name="BasicFOP" minOccurs="0">
209− <annotation>
210− <documentation>BasicFOP cannot combine with .../BSP_Ticketing, or .../SabreSonicTicketing, or .../Multiple CC_FOP.</documentation>
211− </annotation>
212− <complexType>
213− <sequence>
214− <element name="CC_Info" minOccurs="0">
215− <complexType>
216− <sequence>
217− <element name="PaymentCard">
218− <complexType>
219− <attribute name="Code" type="string" use="optional">
220− <annotation>
221− <documentation>"Code" is used to specify a credit card vendor code.</documentation>
222− </annotation>
223− </attribute>
224− <attribute name="CardSecurityCode" type="string" use="optional">
225− <annotation>
226− <documentation>"CardSecurityCode" is used to specify a credit card Card Security Code number.</documentation>
227− </annotation>
228− </attribute>
229− <attribute name="ExpireDate" type="spct:expireDate" use="optional">
230− <annotation>
231− <documentation>"ExpireDate" is used to specify a credit card expiration date, follows this format: YYYY-MM.</documentation>
232− </annotation>
233− </attribute>
234− <attribute name="ExtendedPayment" type="integer" use="optional">
235− <annotation>
236− <documentation>"ExtendedPayment" is used to specify extended payment if applicable.</documentation>
237− </annotation>
238− </attribute>
239− <attribute name="ManualApprovalCode" type="string" use="optional">
240− <annotation>
241− <documentation>"ManualApprovalCode" is used to specify a manual credit card approval code if applicable.</documentation>
242− </annotation>
243− </attribute>
244− <attribute name="Number" type="integer" use="optional">
245− <annotation>
246− <documentation>"Number" is used to specify a credit card number.</documentation>
247− </annotation>
248− </attribute>
249− </complexType>
250− </element>
251− </sequence>
252− <attribute name="Suppress" type="boolean" use="optional">
253− <annotation>
254− <documentation>"Suppress" is used to specify whether or not to suppress credit card information on an itinerary.</documentation>
255− </annotation>
256− </attribute>
257− </complexType>
258− </element>
259− </sequence>
260− <attribute name="Reference" type="integer" use="optional"/>
261− <attribute name="Type" type="string" use="optional">
262− <annotation>
263− <documentation>"Type" is used to specify the payment type. Acceptable values are "CA," (cash) "CK," (check) "CQ," (cheque). If utilizing a credit card please omit @Type, and populate the .../CC_Info child node.</documentation>
264− </annotation>
265− </attribute>
266− <attribute name="Virtual" type="string" use="optional"/>
267− </complexType>
268− </element>
269− <element name="BSP_Ticketing" minOccurs="0">
270− <complexType>
271− <sequence>
272− <element name="MultipleFOP" minOccurs="0">
273− <annotation>
274− <documentation>MultipleFOP cannot combine with .../MultipleMiscFOP, or .../PayLaterPlan</documentation>
275− </annotation>
276− <complexType>
277− <sequence>
278− <element name="Fare">
279− <complexType>
280− <attribute name="Amount" type="string" use="required">
281− <annotation>
282− <documentation>"Amount" is used to specify the amount to be applied to the second FOP.</documentation>
283− </annotation>
284− </attribute>
285− </complexType>
286− </element>
287− <element name="FOP_One">
288− <complexType>
289− <sequence>
290− <element name="CC_Info" minOccurs="0">
291− <complexType>
292− <sequence>
293− <element name="PaymentCard">
294− <complexType>
295− <attribute name="Code" type="string" use="required">
296− <annotation>
297− <documentation>"Code" is used to specify the credit card vendor code.</documentation>
298− </annotation>
299− </attribute>
300− <attribute name="CardSecurityCode" type="string" use="optional">
301− <annotation>
302− <documentation>"CardSecurityCode" is used to specify a credit card Card Security Code number.</documentation>
303− </annotation>
304− </attribute>
305− <attribute name="ExpireDate" type="spct:expireDate" use="required">
306− <annotation>
307− <documentation>"ExpireDate" is used to specify the credit card expiration date, follows this format: YYYY-MM.</documentation>
308− </annotation>
309− </attribute>
310− <attribute name="ExtendedPayment" type="integer" use="optional">
311− <annotation>
312− <documentation>"ExtendedPayment" is used to specify extended payment if applicable.</documentation>
313− </annotation>
314− </attribute>
315− <attribute name="ManualApprovalCode" type="string" use="optional">
316− <annotation>
317− <documentation>"ManualApprovalCode" is used to specify a manual credit card approval code if applicable.</documentation>
318− </annotation>
319− </attribute>
320− <attribute name="ManualOBFee" type="string" use="optional">
321− <annotation>
322− <documentation>"ManualOBFee" is used to indicate that the manual OB fee should be associated to the card. A manual OB fee can ONLY be added to a ticketing entry that references a PQ that has the PRICE-MANUAL tag at the bottom of the *PQ</documentation>
323− </annotation>
324− </attribute>
325− <attribute name="Number" type="integer" use="required">
326− <annotation>
327− <documentation>"Number" is used to specify the credit card number.</documentation>
328− </annotation>
329− </attribute>
330− </complexType>
331− </element>
332− </sequence>
333− <attribute name="Suppress" type="boolean" use="optional">
334− <annotation>
335− <documentation>"Suppress" is used to specify whether or not to suppress credit card information on an itinerary.</documentation>
336− </annotation>
337− </attribute>
338− </complexType>
339− </element>
340− </sequence>
341− <attribute name="Type" type="string" use="optional">
342− <annotation>
343− <documentation>"Type" is used to specify the payment type. Acceptable values are "CA,"CK," or "CQ." If utilizing a credit card please omit @Type, and populate the .../CC_Info child node.</documentation>
344− </annotation>
345− </attribute>
346− </complexType>
347− </element>
348− <element name="FOP_Two">
349− <complexType>
350− <sequence>
351− <element name="CC_Info" minOccurs="0">
352− <complexType>
353− <sequence>
354− <element name="PaymentCard">
355− <complexType>
356− <attribute name="Code" type="string" use="required">
357− <annotation>
358− <documentation>"Code" is used to specify the credit card vendor code.</documentation>
359− </annotation>
360− </attribute>
361− <attribute name="CardSecurityCode" type="string" use="optional">
362− <annotation>
363− <documentation>"CardSecurityCode" is used to specify a credit card Card Security Code number.</documentation>
364− </annotation>
365− </attribute>
366− <attribute name="ExpireDate" type="spct:expireDate" use="required">
367− <annotation>
368− <documentation>"ExpireDate" is used to specify the credit card expiration date, follows this format: YYYY-MM.</documentation>
369− </annotation>
370− </attribute>
371− <attribute name="ExtendedPayment" type="integer" use="optional">
372− <annotation>
373− <documentation>"ExtendedPayment" is used to specify extended payment if applicable.</documentation>
374− </annotation>
375− </attribute>
376− <attribute name="ManualApprovalCode" type="string" use="optional">
377− <annotation>
378− <documentation>"ManualApprovalCode" is used to specify a manual credit card approval code if applicable.</documentation>
379− </annotation>
380− </attribute>
381− <attribute name="ManualOBFee" type="string" use="optional">
382− <annotation>
383− <documentation>b"ManualOBFee" is used to indicate that the manual OB fee should be associated to the card. A manual OB fee can ONLY be added to a ticketing entry that references a PQ that has the PRICE-MANUAL tag at the bottom of the *PQ</documentation>
384− </annotation>
385− </attribute>
386− <attribute name="Number" type="integer" use="required">
387− <annotation>
388− <documentation>"Number" is used to specify the credit card number.</documentation>
389− </annotation>
390− </attribute>
391− </complexType>
392− </element>
393− </sequence>
394− <attribute name="Suppress" type="boolean" use="optional">
395− <annotation>
396− <documentation>"Suppress" is used to specify whether or not to suppress credit card information on an itinerary.</documentation>
397− </annotation>
398− </attribute>
399− </complexType>
400− </element>
401− </sequence>
402− <attribute name="Type" type="string" use="optional">
403− <annotation>
404− <documentation>"Type" is used to specify the payment type. Acceptable values are "CA,"CK," or "CQ." If utilizing a credit card please omit @Type, and populate the .../CC_Info child node.</documentation>
405− </annotation>
406− </attribute>
407− </complexType>
408− </element>
409− <element name="Taxes" minOccurs="0">
410− <complexType>
411− <sequence>
412− <element name="Tax" maxOccurs="3">
413− <complexType>
414− <attribute name="Amount" type="string" use="required">
415− <annotation>
416− <documentation>"Amount" is used to specify the tax amount.</documentation>
417− </annotation>
418− </attribute>
419− <attribute name="TaxCode" type="string" use="required">
420− <annotation>
421− <documentation>"TaxCode" is used to specify the tax code.</documentation>
422− </annotation>
423− </attribute>
424− </complexType>
425− </element>
426− </sequence>
427− </complexType>
428− </element>
429− </sequence>
430− </complexType>
431− </element>
432− <element name="MultipleMiscFOP" minOccurs="0">
433− <annotation>
434− <documentation>MultipleMiscFOP cannot combine with .../MultipleFOP, or .../PayLaterPlan.</documentation>
435− </annotation>
436− <complexType>
437− <sequence>
438− <element name="Fare">
439− <complexType>
440− <attribute name="Amount" type="string" use="required">
441− <annotation>
442− <documentation>"Amount" is used to specify the fare amount to be applied to the second FOP.</documentation>
443− </annotation>
444− </attribute>
445− </complexType>
446− </element>
447− <element name="FOP_One">
448− <complexType>
449− <sequence>
450− <element name="CC_Info" minOccurs="0">
451− <complexType>
452− <sequence>
453− <element name="PaymentCard">
454− <complexType>
455− <attribute name="Code" type="string" use="required">
456− <annotation>
457− <documentation>"Code" is used to specify the credit card vendor code.</documentation>
458− </annotation>
459− </attribute>
460− <attribute name="ExpireDate" type="spct:expireDate" use="required">
461− <annotation>
462− <documentation>"ExpireDate" is used to specify the credit card expiration date, follows this format: YYYY-MM.</documentation>
463− </annotation>
464− </attribute>
465− <attribute name="ExtendedPayment" type="integer" use="optional">
466− <annotation>
467− <documentation>"ExtendedPayment" is used to specify extended payment if applicable.</documentation>
468− </annotation>
469− </attribute>
470− <attribute name="ManualApprovalCode" type="string" use="optional">
471− <annotation>
472− <documentation>"ManualApprovalCode" is used to specify a manual credit card approval code if applicable.</documentation>
473− </annotation>
474− </attribute>
475− <attribute name="Number" type="integer" use="required">
476− <annotation>
477− <documentation>"Number" is used to specify the credit card number.</documentation>
478− </annotation>
479− </attribute>
480− </complexType>
481− </element>
482− </sequence>
483− <attribute name="Suppress" type="boolean" use="optional">
484− <annotation>
485− <documentation>"Suppress" is used to specify whether or not to suppress credit card information on an itinerary.</documentation>
486− </annotation>
487− </attribute>
488− </complexType>
489− </element>
490− </sequence>
491− <attribute name="Type" type="string" use="optional">
492− <annotation>
493− <documentation>"Type" is used to specify the payment type. Acceptable values are "CA,"CK," or "CQ." If utilizing a credit card please omit @Type, and populate the .../CC_Info child node.</documentation>
494− </annotation>
495− </attribute>
496− </complexType>
497− </element>
498− <element name="FOP_Two">
499− <complexType>
500− <sequence>
501− <element name="ExtendedPayment" minOccurs="0">
502− <complexType>
503− <attribute name="NumMonths" type="integer" use="required"/>
504− </complexType>
505− </element>
506− </sequence>
507− <attribute name="Type" type="string" use="required"/>
508− </complexType>
509− </element>
510− <element name="Taxes" minOccurs="0">
511− <complexType>
512− <sequence>
513− <element name="Tax" maxOccurs="2">
514− <complexType>
515− <attribute name="Amount" type="string" use="required">
516− <annotation>
517− <documentation>"Amount" is used to specify the tax amount.</documentation>
518− </annotation>
519− </attribute>
520− <attribute name="TaxCode" type="string" use="required">
521− <annotation>
522− <documentation>"TaxCode" is used to specify the tax code.</documentation>
523− </annotation>
524− </attribute>
525− </complexType>
526− </element>
527− </sequence>
528− </complexType>
529− </element>
530− </sequence>
531− </complexType>
532− </element>
533− <element name="PayLaterPlan" minOccurs="0">
534− <annotation>
535− <documentation>"PayLaterPlan" is only applicable to Brazil, cannot combine with MultipleFOP, or MultipleMiscFOP.</documentation>
536− </annotation>
537− <complexType>
538− <sequence>
539− <element name="Fare">
540− <complexType>
541− <attribute name="Amount" type="string" use="required">
542− <annotation>
543− <documentation>"Amount" is used to specify the remaining fare amount.</documentation>
544− </annotation>
545− </attribute>
546− </complexType>
547− </element>
548− <element name="FOP">
549− <complexType>
550− <sequence>
551− <element name="CC_Info" minOccurs="0">
552− <complexType>
553− <sequence>
554− <element name="PaymentCard">
555− <complexType>
556− <attribute name="Code" type="string" use="required">
557− <annotation>
558− <documentation>"Code" is used to specify the credit card vendor code.</documentation>
559− </annotation>
560− </attribute>
561− <attribute name="ExpireDate" type="spct:expireDate" use="required">
562− <annotation>
563− <documentation>"ExpireDate" is used to specify the credit card expiration date, follows this format: YYYY-MM</documentation>
564− </annotation>
565− </attribute>
566− <attribute name="ManualApprovalCode" type="string" use="optional">
567− <annotation>
568− <documentation>"ManualApprovalCode" is used to specify a manual credit card approval code if applicable.</documentation>
569− </annotation>
570− </attribute>
571− <attribute name="Number" type="integer" use="required">
572− <annotation>
573− <documentation>"Number" is used to specify the credit card number.</documentation>
574− </annotation>
575− </attribute>
576− </complexType>
577− </element>
578− </sequence>
579− </complexType>
580− </element>
581− </sequence>
582− <attribute name="Type" type="string" use="optional">
583− <annotation>
584− <documentation>"Type" is used to specify the payment type. Acceptable values are "CA,"CK," or "CQ." If utilizing a credit card please omit @Type, and populate the .../CC_Info child node.</documentation>
585− </annotation>
586− </attribute>
587− </complexType>
588− </element>
589− <element name="Installment">
590− <complexType>
591− <attribute name="Count" type="string" use="required">
592− <annotation>
593− <documentation>"Count" is used to specify the number of installments.</documentation>
594− </annotation>
595− </attribute>
596− <attribute name="PayLaterReferenceNumber" type="string" use="required">
597− <annotation>
598− <documentation>"PayLaterReferenceNumber" is used to specify the pay later reference number.</documentation>
599− </annotation>
600− </attribute>
601− <attribute name="Value" type="string" use="required">
602− <annotation>
603− <documentation>"Value" is used to specify the value of the installments. Please note that decimals are not permitted.</documentation>
604− </annotation>
605− </attribute>
606− </complexType>
607− </element>
608− </sequence>
609− </complexType>
610− </element>
611− </sequence>
612− </complexType>
613− </element>
614− <element name="MultipleCC_FOP" minOccurs="0">
615− <annotation>
616− <documentation>Multiple CC_FOP cannot combine with .../BSP_Ticketing, or .../SabreSonicTicketing</documentation>
617− </annotation>
618− <complexType>
619− <sequence>
620− <element name="Fare">
621− <complexType>
622− <attribute name="Amount" type="string" use="required">
623− <annotation>
624− <documentation>"Amount" is used to specify the amount to be applied to the second CC.</documentation>
625− </annotation>
626− </attribute>
627− </complexType>
628− </element>
629− <element name="CC_One">
630− <complexType>
631− <sequence>
632− <element name="CC_Info" minOccurs="0">
633− <complexType>
634− <sequence>
635− <element name="PaymentCard">
636− <complexType>
637− <attribute name="Code" type="string" use="required">
638− <annotation>
639− <documentation>"Code" is used to specify the credit card vendor code.</documentation>
640− </annotation>
641− </attribute>
642− <attribute name="CardSecurityCode" type="string" use="optional">
643− <annotation>
644− <documentation>"CardSecurityCode" is used to specify a credit card Card Security Code number.</documentation>
645− </annotation>
646− </attribute>
647− <attribute name="ExpireDate" type="spct:expireDate" use="required">
648− <annotation>
649− <documentation>"ExpireDate" is used to specify the credit card expiration date, follows this format: YYYY-MM</documentation>
650− </annotation>
651− </attribute>
652− <attribute name="ExtendedPayment" type="integer" use="optional">
653− <annotation>
654− <documentation>"ExtendedPayment" is used to specify extended payment if applicable.</documentation>
655− </annotation>
656− </attribute>
657− <attribute name="ManualApprovalCode" type="string" use="optional">
658− <annotation>
659− <documentation>"ManualApprovalCode" is used to specify a manual credit card if applicable.</documentation>
660− </annotation>
661− </attribute>
662− <attribute name="ManualOBFee" type="string" use="optional">
663− <annotation>
664− <documentation>"ManualOBFee" is used to indicate that the manual OB fee should be associated to the card. A manual OB fee can ONLY be added to a ticketing entry that references a PQ that has the PRICE-MANUAL tag at the bottom of the *PQ</documentation>
665− </annotation>
666− </attribute>
667− <attribute name="Number" type="integer" use="required">
668− <annotation>
669− <documentation>"Number" is used to specify the credit card number.</documentation>
670− </annotation>
671− </attribute>
672− </complexType>
673− </element>
674− </sequence>
675− <attribute name="Suppress" type="boolean" use="optional">
676− <annotation>
677− <documentation>"Suppress" is used to specify whether or not to suppress credit card information on an itinerary.</documentation>
678− </annotation>
679− </attribute>
680− </complexType>
681− </element>
682− </sequence>
683− </complexType>
684− </element>
685− <element name="CC_Two">
686− <complexType>
687− <sequence>
688− <element name="CC_Info" minOccurs="0">
689− <complexType>
690− <sequence>
691− <element name="PaymentCard">
692− <complexType>
693− <attribute name="Code" type="string" use="required">
694− <annotation>
695− <documentation>"Code" is used to specify the credit card vendor code.</documentation>
696− </annotation>
697− </attribute>
698− <attribute name="CardSecurityCode" type="string" use="optional">
699− <annotation>
700− <documentation>"CardSecurityCode" is used to specify a credit card Card Security Code number.</documentation>
701− </annotation>
702− </attribute>
703− <attribute name="ExpireDate" type="spct:expireDate" use="required">
704− <annotation>
705− <documentation>"ExpireDate" is used to specify the credit card expiration date, follows this format: YYYY-MM</documentation>
706− </annotation>
707− </attribute>
708− <attribute name="ExtendedPayment" type="integer" use="optional">
709− <annotation>
710− <documentation>"ExtendedPayment" is used to specify extended payment if applicable.</documentation>
711− </annotation>
712− </attribute>
713− <attribute name="ManualApprovalCode" type="string" use="optional">
714− <annotation>
715− <documentation>"ManualApprovalCode" is used to specify a manual credit card if applicable.</documentation>
716− </annotation>
717− </attribute>
718− <attribute name="ManualOBFee" type="string" use="optional">
719− <annotation>
720− <documentation>"ManualOBFee" is used to indicate that the manual OB fee should be associated to the card. A manual OB fee can ONLY be added to a ticketing entry that references a PQ that has the 'PRICE-MANUAL' tag at the bottom of the *PQ</documentation>
721− </annotation>
722− </attribute>
723− <attribute name="Number" type="integer" use="required">
724− <annotation>
725− <documentation>"Number" is used to specify the credit card number.</documentation>
726− </annotation>
727− </attribute>
728− </complexType>
729− </element>
730− </sequence>
731− <attribute name="Suppress" type="boolean" use="optional">
732− <annotation>
733− <documentation>"Suppress" is used to specify whether or not to suppress credit card information on an itinerary.</documentation>
734− </annotation>
735− </attribute>
736− </complexType>
737− </element>
738− </sequence>
739− </complexType>
740− </element>
741− </sequence>
742− </complexType>
743− </element>
744− <element name="SabreSonicTicketing" minOccurs="0">
745− <annotation>
746− <documentation>"SabreSonicTicketing" is only valid for SabreSonic-based airlines, cannot combine with .../BSP_Ticketing, or .../Multiple CC_FOP.</documentation>
747− </annotation>
748− <complexType>
749− <sequence>
750− <element name="BasicFOP" minOccurs="0">
751− <complexType>
752− <sequence>
753− <element name="CC_Info" minOccurs="0">
754− <complexType>
755− <sequence>
756− <element name="PaymentCard">
757− <complexType>
758− <attribute name="CardSecurityCode" type="integer" use="optional">
759− <annotation>
760− <documentation>"CardSecurityCode" is used to specify a credit card security code.</documentation>
761− </annotation>
762− </attribute>
763− <attribute name="Code" type="string" use="required">
764− <annotation>
765− <documentation>"Code" is used to specify a credit card vendor code.</documentation>
766− </annotation>
767− </attribute>
768− <attribute name="ExpireDate" type="spct:expireDate" use="required">
769− <annotation>
770− <documentation>"ExpireDate" is used to specify a credit card expiration date, follows this format: YYYY-MM.</documentation>
771− </annotation>
772− </attribute>
773− <attribute name="ExtendedPayment" type="integer" use="optional">
774− <annotation>
775− <documentation>"ExtendedPayment" is used to specify extended payment if applicable.</documentation>
776− </annotation>
777− </attribute>
778− <attribute name="ManualApprovalCode" type="string" use="optional">
779− <annotation>
780− <documentation>"ManualApprovalCode" is used to specify a manual credit card approval code if applicable.</documentation>
781− </annotation>
782− </attribute>
783− <attribute name="Number" type="integer" use="required">
784− <annotation>
785− <documentation>"Number" is used to specify a credit card number.</documentation>
786− </annotation>
787− </attribute>
788− </complexType>
789− </element>
790− </sequence>
791− <attribute name="Suppress" type="boolean" use="optional">
792− <annotation>
793− <documentation>"Suppress" is used to specify whether or not to suppress credit card information on an itinerary.</documentation>
794− </annotation>
795− </attribute>
796− </complexType>
797− </element>
798− </sequence>
799− <attribute name="ManualApprovalCode" type="string" use="optional">
800− <annotation>
801− <documentation>"ManualApprovalCode" is used to specify a manual approval code for non-credit card forms of payment.</documentation>
802− </annotation>
803− </attribute>
804− <attribute name="Type" type="string" use="optional">
805− <annotation>
806− <documentation>"Type" is used to specify the payment type. Acceptable values are "CA," (cash) "CK," (check) "CQ," (cheque) "PT," "PTACA," (PTA cash) "PTAGTCK." (PTA agency check) or "PTCK" (PTA check). If utilizing a credit card please omit @Type, and populate the .../CC_Info child node, unless needing to specify a PTA credit card form of payment. For a PTA credit card form of payment the client should pass Type="PT" and populate the .../CC_Info child node with the relevant credit card information.</documentation>
807− </annotation>
808− </attribute>
809− </complexType>
810− </element>
811− <element name="EnhancedMultipleFOP" minOccurs="0">
812− <annotation>
813− <documentation>EnhancedMultipleCC_FOP is only valid for SabreSonic-based airlines who have actived the enhanced multiple form of payment option, cannot combine with .../MultipleFOP.</documentation>
814− </annotation>
815− <complexType>
816− <sequence>
817− <element name="Fare">
818− <complexType>
819− <attribute name="Amount" type="string" use="required">
820− <annotation>
821− <documentation>"Amount" is used to specify the fare amount to be applied to the second FOP.</documentation>
822− </annotation>
823− </attribute>
824− </complexType>
825− </element>
826− <element name="FOP_One">
827− <complexType>
828− <sequence>
829− <element name="CC_Info" minOccurs="0">
830− <complexType>
831− <sequence>
832− <element name="PaymentCard">
833− <complexType>
834− <attribute name="CardSecurityCode" type="string" use="optional">
835− <annotation>
836− <documentation>"CardSecurityCode" is used to specify a credit card security code.</documentation>
837− </annotation>
838− </attribute>
839− <attribute name="Code" type="string" use="required">
840− <annotation>
841− <documentation>"Code" is used to specify the credit card vendor code.</documentation>
842− </annotation>
843− </attribute>
844− <attribute name="ExpireDate" type="spct:expireDate" use="required">
845− <annotation>
846− <documentation>"ExpireDate" is used to specify the credit card expiration date, follows this format: YYYY-MM.</documentation>
847− </annotation>
848− </attribute>
849− <attribute name="ExtendedPayment" type="integer" use="optional">
850− <annotation>
851− <documentation>"ExtendedPayment" is used to specify extended payment if applicable.</documentation>
852− </annotation>
853− </attribute>
854− <attribute name="ManualApprovalCode" type="string" use="optional">
855− <annotation>
856− <documentation>"ManualApprovalCode" is used to specify a manual credit card approval code if applicable.</documentation>
857− </annotation>
858− </attribute>
859− <attribute name="Number" type="integer" use="required">
860− <annotation>
861− <documentation>"Number" is used to specify the credit card number.</documentation>
862− </annotation>
863− </attribute>
864− </complexType>
865− </element>
866− </sequence>
867− </complexType>
868− </element>
869− </sequence>
870− <attribute name="Type" type="string" use="optional"/>
871− </complexType>
872− </element>
873− <element name="FOP_Two">
874− <complexType>
875− <sequence>
876− <element name="CC_Info" minOccurs="0">
877− <complexType>
878− <sequence>
879− <element name="PaymentCard">
880− <complexType>
881− <attribute name="CardSecurityCode" type="string" use="optional">
882− <annotation>
883− <documentation>"CardSecurityCode" is used to specify a credit card security code.</documentation>
884− </annotation>
885− </attribute>
886− <attribute name="Code" type="string" use="required">
887− <annotation>
888− <documentation>"Code" is used to specify the credit card vendor code.</documentation>
889− </annotation>
890− </attribute>
891− <attribute name="ExpireDate" type="spct:expireDate" use="required">
892− <annotation>
893− <documentation>"ExpireDate" is used to specify the credit card expiration date, follows this format: YYYY-MM.</documentation>
894− </annotation>
895− </attribute>
896− <attribute name="ExtendedPayment" type="integer" use="optional">
897− <annotation>
898− <documentation>"ExtendedPayment" is used to specify extended payment if applicable.</documentation>
899− </annotation>
900− </attribute>
901− <attribute name="ManualApprovalCode" type="string" use="optional">
902− <annotation>
903− <documentation>"ManualApprovalCode" is used to specify a manual credit card approval code if applicable.</documentation>
904− </annotation>
905− </attribute>
906− <attribute name="Number" type="integer" use="required">
907− <annotation>
908− <documentation>"Number" is used to specify the credit card number.</documentation>
909− </annotation>
910− </attribute>
911− </complexType>
912− </element>
913− </sequence>
914− </complexType>
915− </element>
916− </sequence>
917− <attribute name="Type" type="string" use="optional"/>
918− </complexType>
919− </element>
920− <element name="Taxes">
921− <complexType>
922− <sequence>
923− <element name="Tax">
924− <complexType>
925− <attribute name="Amount" type="string" use="required">
926− <annotation>
927− <documentation>"Amount" is used to specify the tax amount.</documentation>
928− </annotation>
929− </attribute>
930− <attribute name="TaxCode" type="string" use="required">
931− <annotation>
932− <documentation>"TaxCode" is used to specify the tax code.</documentation>
933− </annotation>
934− </attribute>
935− </complexType>
936− </element>
937− </sequence>
938− </complexType>
939− </element>
940− </sequence>
941− </complexType>
942− </element>
943− <element name="MultipleFOP" minOccurs="0">
944− <annotation>
945− <documentation>MultipleFOP cannot combine with .../EnhancedMultipleFOP.</documentation>
946− </annotation>
947− <complexType>
948− <sequence>
949− <element name="Fare">
950− <complexType>
951− <attribute name="Amount" type="string" use="required">
952− <annotation>
953− <documentation>"Amount" is used to specify the fare amount to be applied to the second FOP.</documentation>
954− </annotation>
955− </attribute>
956− </complexType>
957− </element>
958− <element name="FOP_One">
959− <complexType>
960− <sequence>
961− <element name="CC_Info" minOccurs="0">
962− <complexType>
963− <sequence>
964− <element name="PaymentCard">
965− <complexType>
966− <attribute name="Code" type="string" use="required">
967− <annotation>
968− <documentation>"Code" is used to specify the credit card vendor code.</documentation>
969− </annotation>
970− </attribute>
971− <attribute name="ManualApprovalCode" type="string" use="optional">
972− <annotation>
973− <documentation>"ManualApprovalCode" is used to specify a manual credit card approval code if applicable.</documentation>
974− </annotation>
975− </attribute>
976− <attribute name="Number" type="integer" use="required">
977− <annotation>
978− <documentation>"Number" is used to specify the credit card number.</documentation>
979− </annotation>
980− </attribute>
981− </complexType>
982− </element>
983− </sequence>
984− </complexType>
985− </element>
986− </sequence>
987− <attribute name="Type" type="string" use="optional">
988− <annotation>
989− <documentation>"Type" is used to specify the payment type. Acceptable values are "CA," (cash) "CK," (check) "CQ," (cheque) "PT," "PTACA," (PTA cash) "PTAGTCK." (PTA agency check) or "PTCK" (PTA check). If utilizing a credit card please omit @Type, and populate the .../CC_Info child node, unless needing to specify a PTA credit card form of payment. For a PTA credit card form of payment the client should pass Type="PT" and populate the .../CC_Info child node with the relevant credit card information.</documentation>
990− </annotation>
991− </attribute>
992− </complexType>
993− </element>
994− <element name="FOP_Two">
995− <complexType>
996− <sequence>
997− <element name="CC_Info" minOccurs="0">
998− <complexType>
999− <sequence>
1000− <element name="PaymentCard">
1001− <complexType>
1002− <attribute name="Code" type="string" use="required">
1003− <annotation>
1004− <documentation>"Code" is used to specify the credit card vendor code.</documentation>
1005− </annotation>
1006− </attribute>
1007− <attribute name="ManualApprovalCode" type="string" use="optional">
1008− <annotation>
1009− <documentation>"ManualApprovalCode" is used to specify a manual credit card approval code if applicable.</documentation>
1010− </annotation>
1011− </attribute>
1012− <attribute name="Number" type="integer" use="required">
1013− <annotation>
1014− <documentation>"Number" is used to specify the credit card number.</documentation>
1015− </annotation>
1016− </attribute>
1017− </complexType>
1018− </element>
1019− </sequence>
1020− </complexType>
1021− </element>
1022− </sequence>
1023− <attribute name="Type" type="string" use="optional">
1024− <annotation>
1025− <documentation>"Type" is used to specify the payment type. Acceptable values are "CA,"CK," or "CQ." If utilizing a credit card please omit @Type, and populate the .../CCInfo child node.</documentation>
1026− </annotation>
1027− </attribute>
1028− </complexType>
1029− </element>
1030− <element name="Taxes" minOccurs="0">
1031− <complexType>
1032− <sequence>
1033− <element name="Tax">
1034− <complexType>
1035− <attribute name="Amount" type="string" use="required">
1036− <annotation>
1037− <documentation>"Amount" is used to specify the tax amount.</documentation>
1038− </annotation>
1039− </attribute>
1040− <attribute name="TaxCode" type="string" use="required">
1041− <annotation>
1042− <documentation>"TaxCode" is used to specify the tax code.</documentation>
1043− </annotation>
1044− </attribute>
1045− </complexType>
1046− </element>
1047− </sequence>
1048− </complexType>
1049− </element>
1050− </sequence>
1051− </complexType>
1052− </element>
1053− </sequence>
1054− </complexType>
1055− </element>
1056− </sequence>
1057− </complexType>
1058− </element>
1059− <element name="MiscQualifiers" minOccurs="0">
1060− <complexType>
1061− <sequence>
1062− <element name="AirExtras" minOccurs="0" maxOccurs="unbounded">
1063− <complexType>
1064− <attribute name="EndNumber" type="integer" use="optional">
1065− <annotation>
1066− <documentation>"EndNumber" is used to specify the final EMD number when specifying a range.</documentation>
1067− </annotation>
1068− </attribute>
1069− <attribute name="Number" type="integer" use="required">
1070− <annotation>
1071− <documentation>"Number" is used to specify and EMD number.</documentation>
1072− </annotation>
1073− </attribute>
1074− </complexType>
1075− </element>
1076− <element name="BaggageAllowance" minOccurs="0">
1077− <annotation>
1078− <documentation>Cannot combine with PhaseIV.</documentation>
1079− </annotation>
1080− <complexType>
1081− <attribute name="Number" type="string" use="optional">
1082− <annotation>
1083− <documentation>"Number" is used to specify the quantity of checked bags if applicable.</documentation>
1084− </annotation>
1085− </attribute>
1086− <attribute name="Weight" type="string" use="optional">
1087− <annotation>
1088− <documentation>"Weight" is used to specify the weight in kilos of checked bags if applicable.</documentation>
1089− </annotation>
1090− </attribute>
1091− </complexType>
1092− </element>
1093− <element name="Certificate" minOccurs="0" maxOccurs="2">
1094− <complexType>
1095− <attribute name="Number" type="string" use="required">
1096− <annotation>
1097− <documentation>"Number" is used to specify a ticket number. Please note that this qualifier is only applicable to Sabre Sonic-hosted carriers.</documentation>
1098− </annotation>
1099− </attribute>
1100− </complexType>
1101− </element>
1102− <element name="Commission" minOccurs="0">
1103− <complexType>
1104− <attribute name="Amount" type="decimal" use="optional">
1105− <annotation>
1106− <documentation>"Amount" is used to specify the numeric amount of commission being claimed if applicable.</documentation>
1107− </annotation>
1108− </attribute>
1109− <attribute name="Percent" type="decimal" use="optional">
1110− <annotation>
1111− <documentation>"Percent" is used to specify the precentage of commission being claimed if applicable.</documentation>
1112− </annotation>
1113− </attribute>
1114− </complexType>
1115− </element>
1116− <element name="DateOfBirth" minOccurs="0">
1117− <annotation>
1118− <documentation>"DOB" is used to instruct the system to take the passenger's date of birth-related information from the SSR PNR field, and pass it into the host-based ticketing application. This is required for clients based in the Russian Federation.</documentation>
1119− </annotation>
1120− </element>
1121− <element name="Endorsement" minOccurs="0">
1122− <complexType>
1123− <sequence>
1124− <element name="Text" type="string"/>
1125− </sequence>
1126− <attribute name="Override" type="boolean" use="optional"/>
1127− </complexType>
1128− </element>
1129− <element name="FutureTicket" minOccurs="0">
1130− <complexType>
1131− <sequence>
1132− <element name="Line" maxOccurs="unbounded">
1133− <annotation>
1134− <documentation>"Line" and its associated attributes are used to issue tickets from specific FP lines.</documentation>
1135− </annotation>
1136− <complexType>
1137− <attribute name="EndNumber" type="integer" use="optional"/>
1138− <attribute name="NameNumber" type="string" use="optional"/>
1139− <attribute name="Number" type="integer" use="required"/>
1140− </complexType>
1141− </element>
1142− </sequence>
1143− </complexType>
1144− </element>
1145− <element name="Invoice" minOccurs="0">
1146− <annotation>
1147− <documentation>"Invoice" is used to specify to print invoice at time of ticketing.</documentation>
1148− </annotation>
1149− <complexType>
1150− <attribute name="Ind" type="boolean" use="optional"/>
1151− <attribute name="ETReceipt" type="boolean" use="optional"/>
1152− </complexType>
1153− </element>
1154− <element name="NeedPrint" minOccurs="0">
1155− <annotation>
1156− <documentation>Please note that only two of the three attributes can be set to true simultaneously.</documentation>
1157− </annotation>
1158− <complexType>
1159− <attribute name="AuditorCoupon" type="boolean" use="required">
1160− <annotation>
1161− <documentation>"AuditorCoupon" is used to specify to print an auditor coupon. Please note that this qualifier is only applicable to Sabre Sonic-hosted carriers.</documentation>
1162− </annotation>
1163− </attribute>
1164− <attribute name="Itinerary" type="boolean" use="required">
1165− <annotation>
1166− <documentation>"Itinerary" is used to specify to print an itinerary. Please note that this qualifier is only applicable to Sabre Sonic-hosted carriers.</documentation>
1167− </annotation>
1168− </attribute>
1169− <attribute name="PassengerReceipt" type="boolean" use="required">
1170− <annotation>
1171− <documentation>"PassengerReceipt" is used to specify to print a passenger receipt. Please note that this qualifier is only applicable to Sabre Sonic-hosted carriers.</documentation>
1172− </annotation>
1173− </attribute>
1174− </complexType>
1175− </element>
1176− <element name="NetRemit" minOccurs="0">
1177− <complexType>
1178− <attribute name="Amount" type="decimal" use="optional"/>
1179− <attribute name="ContractAgreementCode" type="string" use="optional"/>
1180− <attribute name="NetCreditAmount" type="decimal" use="optional"/>
1181− <attribute name="ValueCode" type="string" use="optional"/>
1182− </complexType>
1183− </element>
1184− <element name="Ticket" minOccurs="0">
1185− <complexType>
1186− <attribute name="Action" type="string" use="optional">
1187− <annotation>
1188− <documentation>"Action" is used to specify an action code. Please note that this qualifier is only applicable to Sabre Sonic-hosted carriers.</documentation>
1189− </annotation>
1190− </attribute>
1191− <attribute name="Type" type="string" use="optional">
1192− <annotation>
1193− <documentation>"Type" is used to specify the type of ticket to issue. Acceptable values for Type: ETR = electronic ticket (default), EMD= Electronic Miscellaneous Document, XETR = paper ticket, VCR = paper ticket (for airline use only).</documentation>
1194− </annotation>
1195− </attribute>
1196− </complexType>
1197− </element>
1198− <element name="TourCode" minOccurs="0">
1199− <complexType>
1200− <sequence>
1201− <element name="SuppressFareReplaceWithBT" minOccurs="0">
1202− <annotation>
1203− <documentation>This is not applicable to ARC subscribers.</documentation>
1204− </annotation>
1205− <complexType>
1206− <attribute name="Ind" type="boolean" use="required">
1207− <annotation>
1208− <documentation>"Ind" is used to specify to suppress the fare amount on the ticket and replace with BT.</documentation>
1209− </annotation>
1210− </attribute>
1211− </complexType>
1212− </element>
1213− <element name="SuppressFareReplaceWithIT" minOccurs="0">
1214− <complexType>
1215− <attribute name="Ind" type="boolean" use="required">
1216− <annotation>
1217− <documentation>"Ind" is used to specify to suppress the fare amount on the ticket and replace with IT.</documentation>
1218− </annotation>
1219− </attribute>
1220− </complexType>
1221− </element>
1222− <element name="SuppressIT" minOccurs="0">
1223− <complexType>
1224− <attribute name="Ind" type="boolean" use="required">
1225− <annotation>
1226− <documentation>"Ind" is used to specify to to suppress the IT in the tourcode box from printing.</documentation>
1227− </annotation>
1228− </attribute>
1229− </complexType>
1230− </element>
1231− <element name="SuppressITSupressFare" minOccurs="0">
1232− <complexType>
1233− <attribute name="Ind" type="boolean" use="required">
1234− <annotation>
1235− <documentation>"Ind" is used to specify to specify to suppress IT from printing in the tour box on the ticket and to suppress fare amounts from printing on the ticket.</documentation>
1236− </annotation>
1237− </attribute>
1238− </complexType>
1239− </element>
1240− <element name="Text" type="string" minOccurs="0"/>
1241− </sequence>
1242− </complexType>
1243− </element>
1244− </sequence>
1245− </complexType>
1246− </element>
1247− <element name="PricingQualifiers" minOccurs="0">
1248− <complexType>
1249− <sequence>
1250− <element name="Brand" minOccurs="0" maxOccurs="unbounded">
1251− <annotation>
1252− <documentation>"Brand" is used to specify a brand. Please note that it's not possible to request more than 1 brand for an entire journey, or for the same segment.</documentation>
1253− </annotation>
1254− <complexType>
1255− <simpleContent>
1256− <extension base="string">
1257− <attribute name="RPH" type="integer" use="optional">
1258− <annotation>
1259− <documentation>"RPH" is used to match up with ".../ItineraryOptions/Segment".</documentation>
1260− </annotation>
1261− </attribute>
1262− </extension>
1263− </simpleContent>
1264− </complexType>
1265− </element>
1266− <element name="FareFocusExclude" minOccurs="0">
1267− <annotation>
1268− <documentation>"FareFocusExclude" is used to exclude fare focus fares based on business rules of the agency. Please note that this qualifier cannot be combined with .../PriceQuote</documentation>
1269− </annotation>
1270− <complexType>
1271− <attribute name="Ind" type="boolean" use="required"/>
1272− </complexType>
1273− </element>
1274− <element name="Fare" minOccurs="0">
1275− <complexType>
1276− <attribute name="Type" type="string" use="required">
1277− <annotation>
1278− <documentation>"Type" is used to specify a fare type. Acceptable values are "NL" for normal fare, "EX" for special fare, and 'IT" for inclusive tour.</documentation>
1279− </annotation>
1280− </attribute>
1281− </complexType>
1282− </element>
1283− <element name="ItineraryOptions" minOccurs="0">
1284− <complexType>
1285− <sequence>
1286− <element name="SegmentSelect" minOccurs="0" maxOccurs="unbounded">
1287− <complexType>
1288− <attribute name="EndNumber" type="integer" use="optional"/>
1289− <attribute name="Number" type="integer" use="required"/>
1290− <attribute name="RPH" type="string" use="optional">
1291− <annotation>
1292− <documentation>"RPH" is used to match up with ".../SpecificFare/@RPH" or .../Brand.</documentation>
1293− </annotation>
1294− </attribute>
1295− </complexType>
1296− </element>
1297− <element name="SideTrip" minOccurs="0">
1298− <annotation>
1299− <documentation>"SideTrip" is used to instruct the system to price the specified itinerary segments as a side trip.</documentation>
1300− </annotation>
1301− <complexType>
1302− <attribute name="EndNumber" type="integer" use="optional"/>
1303− <attribute name="Number" type="integer" use="required"/>
1304− </complexType>
1305− </element>
1306− </sequence>
1307− </complexType>
1308− </element>
1309− <element name="NameSelect" minOccurs="0" maxOccurs="unbounded">
1310− <annotation>
1311− <documentation>"NameSelect" is used to instruct the system to price theitinerary based upon a particular name field.</documentation>
1312− </annotation>
1313−
1314− <complexType>
1315− <attribute name="EndNameNumber" type="string" use="optional"/>
1316− <attribute name="NameNumber" type="string" use="required"/>
1317− </complexType>
1318− </element>
1319− <element name="PhaseIV" minOccurs="0" maxOccurs="7">
1320− <annotation>
1321− <documentation>Cannot combine with .../PriceQuote.</documentation>
1322− </annotation>
1323− <complexType>
1324− <sequence>
1325− <element name="NameSelect" minOccurs="0" maxOccurs="unbounded">
1326− <annotation>
1327− <documentation>"NameSelect" is used to instruct the system to price theitinerary based upon a particular name field.</documentation>
1328− </annotation>
1329− <complexType>
1330− <attribute name="EndNameNumber" type="string" use="optional"/>
1331− <attribute name="NameNumber" type="string" use="required"/>
1332− </complexType>
1333− </element>
1334− </sequence>
1335− <attribute name="Number" type="integer" use="required"/>
1336− </complexType>
1337− </element>
1338− <element name="PriceQuote" minOccurs="0" maxOccurs="unbounded">
1339− <annotation>
1340− <documentation>Cannot combine with .../NameSelect. Cannot combine with .../PhaseIV.</documentation>
1341− </annotation>
1342− <complexType>
1343− <sequence>
1344− <element name="NameSelect" minOccurs="0" maxOccurs="unbounded">
1345− <annotation>
1346− <documentation>"NameSelect" is used to instruct the system to price theitinerary based upon a particular name field.</documentation>
1347− </annotation>
1348− <complexType>
1349− <attribute name="EndNameNumber" type="decimal" use="optional"/>
1350− <attribute name="NameNumber" type="decimal" use="required"/>
1351− </complexType>
1352− </element>
1353− <element name="Record" minOccurs="0" maxOccurs="unbounded">
1354− <annotation>
1355− <documentation>In order to specify multiple PQR records to be issued please specify a range or specific record numbers by means of the element repetition. .../Ticketing/PricingQualifiers/PriceQuote/Record/@Reissue cannot be combined with .../Ticketing/MiscQualifiers/Ticket</documentation>
1356− </annotation>
1357− <complexType>
1358− <attribute name="EndNumber" type="integer" use="optional">
1359− <annotation>
1360− <documentation>"EndNumber" is used to specify the ending PQ number in a range.</documentation>
1361− </annotation>
1362− </attribute>
1363− <attribute name="Number" type="integer" use="required">
1364− <annotation>
1365− <documentation>"Number" is used to specify a PQ number.</documentation>
1366− </annotation>
1367− </attribute>
1368− <attribute name="Reissue" type="boolean" use="optional">
1369− <annotation>
1370− <documentation>"Reissue" is used to indicate that the particular PQ record is a PQ Reissue record.</documentation>
1371− </annotation>
1372− </attribute>
1373− </complexType>
1374− </element>
1375− </sequence>
1376− </complexType>
1377− </element>
1378− <element name="RefundableBalance" minOccurs="0">
1379− <complexType>
1380− <sequence>
1381− <element name="Taxes" minOccurs="0">
1382− <complexType>
1383− <sequence>
1384− <element name="Tax" maxOccurs="unbounded">
1385− <complexType>
1386− <attribute name="Amount" type="string" use="required"/>
1387− <attribute name="Code" type="string" use="required"/>
1388− </complexType>
1389− </element>
1390− </sequence>
1391− </complexType>
1392− </element>
1393− </sequence>
1394− <attribute name="Amount" type="string" use="required"/>
1395− </complexType>
1396− </element>
1397− <element name="SpanishLargeFamilyDiscountLevel" minOccurs="0">
1398− <annotation>
1399− <documentation>"SpanishLargeFamilyDiscountLevel" is used to specify the Spanish large family discount level. Please note that this qualifier is only applicable to Spain-based subscribers.</documentation>
1400− </annotation>
1401− <simpleType>
1402− <restriction base="string">
1403− <enumeration value="1"/>
1404− <enumeration value="2"/>
1405− </restriction>
1406− </simpleType>
1407− </element>
1408− <element name="SpecificFare" minOccurs="0" maxOccurs="unbounded">
1409− <annotation>
1410− <documentation>Please note that the element is only applicable to Abacus.</documentation>
1411− </annotation>
1412− <complexType>
1413− <sequence>
1414− <element name="FareBasis" type="string" minOccurs="0"/>
1415− </sequence>
1416− <attribute name="RPH" type="string" use="optional">
1417− <annotation>
1418− <documentation>"RPH" is used to match up with ../OptionalQualifiers/PricingQualifiers/ItineraryOptions/Segment.</documentation>
1419− </annotation>
1420− </attribute>
1421− </complexType>
1422− </element>
1423− <element name="SpecificPenalty" minOccurs="0">
1424− <annotation>
1425− <documentation>"SpecificPenalty" is used to specify change or cancellation amounts for an itinerary.</documentation>
1426− </annotation>
1427− <complexType>
1428− <sequence>
1429− <element name="Changeable" minOccurs="0">
1430− <annotation>
1431− <documentation>It is not possible to combine "BeforeDeparture" and "AfterDeparture" within one element.</documentation>
1432− </annotation>
1433− <complexType>
1434− <attribute name="Any" type="boolean" use="optional">
1435− <annotation>
1436− <documentation>"Any" is used to specify only changeable fare options.</documentation>
1437− </annotation>
1438− </attribute>
1439− <attribute name="CurrencyCode" type="string" use="optional">
1440− <annotation>
1441− <documentation>"CurrencyCode" is used to specify the specific currency for maximum exchange penalty.</documentation>
1442− </annotation>
1443− </attribute>
1444− <attribute name="MaxPenalty" type="string" use="optional">
1445− <annotation>
1446− <documentation>"MaxPenalty" is used to specify maximum change penalty. If a value of "0" is input no penalty is preferred. If a value of "N" is input only non-changeable options are requested. Please note that monetary amount that includes a decimal is not allowed</documentation>
1447− </annotation>
1448− </attribute>
1449− <attribute name="BeforeDeparture" type="boolean" use="optional">
1450− <annotation>
1451− <documentation>"BeforeDeparture" is used to query for before depature fees.</documentation>
1452− </annotation>
1453− </attribute>
1454− <attribute name="AfterDeparture" type="boolean" use="optional">
1455− <annotation>
1456− <documentation>"AfterDeparture" is used to query for after depature fees.</documentation>
1457− </annotation>
1458− </attribute>
1459− </complexType>
1460− </element>
1461− <element name="EitherOr" minOccurs="0">
1462− <annotation>
1463− <documentation>It is not possible to combine "BeforeDeparture" and "AfterDeparture" within one element.</documentation>
1464− </annotation>
1465− <complexType>
1466− <attribute name="Any" type="boolean" use="optional">
1467− <annotation>
1468− <documentation>"Any" is used to specify only changeable fare options.</documentation>
1469− </annotation>
1470− </attribute>
1471− <attribute name="CurrencyCode" type="string" use="optional">
1472− <annotation>
1473− <documentation>"CurrencyCode" is used to specify the specific currency for maximum exchange penalty.</documentation>
1474− </annotation>
1475− </attribute>
1476− <attribute name="MaxPenalty" type="string" use="optional">
1477− <annotation>
1478− <documentation>"MaxPenalty" is used to specify maximum change penalty. If a value of "0" is input no penalty is preferred. If a value of "N" is input only non-changeable options are requested. Please note that monetary amount that includes a decimal is not allowed</documentation>
1479− </annotation>
1480− </attribute>
1481− <attribute name="BeforeDeparture" type="boolean" use="optional">
1482− <annotation>
1483− <documentation>"BeforeDeparture" is used to query for before depature fees.</documentation>
1484− </annotation>
1485− </attribute>
1486− <attribute name="AfterDeparture" type="boolean" use="optional">
1487− <annotation>
1488− <documentation>"AfterDeparture" is used to query for after depature fees.</documentation>
1489− </annotation>
1490− </attribute>
1491− </complexType>
1492− </element>
1493− <element name="Refundable" minOccurs="0">
1494− <annotation>
1495− <documentation>It is not possible to combine "BeforeDeparture" and "AfterDeparture" within one element.</documentation>
1496− </annotation>
1497− <complexType>
1498− <attribute name="Any" type="boolean" use="optional">
1499− <annotation>
1500− <documentation>"Any" is used to specify only changeable fare options.</documentation>
1501− </annotation>
1502− </attribute>
1503− <attribute name="CurrencyCode" type="string" use="optional">
1504− <annotation>
1505− <documentation>"CurrencyCode" is used to specify the specific currency for maximum exchange penalty.</documentation>
1506− </annotation>
1507− </attribute>
1508− <attribute name="MaxPenalty" type="string" use="optional">
1509− <annotation>
1510− <documentation>"MaxPenalty" is used to specify maximum change penalty. If a value of "0" is input no penalty is preferred. If a value of "N" is input only non-changeable options are requested. Please note that monetary amount that includes a decimal is not allowed</documentation>
1511− </annotation>
1512− </attribute>
1513− <attribute name="BeforeDeparture" type="boolean" use="optional">
1514− <annotation>
1515− <documentation>"BeforeDeparture" is used to query for before depature fees.</documentation>
1516− </annotation>
1517− </attribute>
1518− <attribute name="AfterDeparture" type="boolean" use="optional">
1519− <annotation>
1520− <documentation>"AfterDeparture" is used to query for after depature fees.</documentation>
1521− </annotation>
1522− </attribute>
1523− </complexType>
1524− </element>
1525− </sequence>
1526− <attribute name="AdditionalInfo" type="boolean" use="optional">
1527− <annotation>
1528− <documentation>"AdditionalInfo" is used to receive additional tags with information on fare flexibility.</documentation>
1529− </annotation>
1530− </attribute>
1531− </complexType>
1532− </element>
1533− <element name="Taxes" minOccurs="0">
1534− <complexType>
1535− <sequence>
1536− <element name="NoTax" minOccurs="0">
1537− <complexType>
1538− <attribute name="Ind" type="boolean" use="optional"/>
1539− </complexType>
1540− </element>
1541− <element name="TaxExempt" minOccurs="0" maxOccurs="5">
1542− <complexType>
1543− <attribute name="Code" type="string" use="optional"/>
1544− </complexType>
1545− </element>
1546− </sequence>
1547− </complexType>
1548− </element>
1549− <element name="ValidityDates" minOccurs="0" maxOccurs="unbounded">
1550− <annotation>
1551− <documentation>This node is used to specify ticket validity dates.Cannot combine with PhaseIV.</documentation>
1552− </annotation>
1553− <complexType>
1554− <sequence>
1555− <element name="NotValidAfter" type="spct:date" minOccurs="0"/>
1556− <element name="NotValidBefore" type="spct:date" minOccurs="0"/>
1557− <element name="Segment" maxOccurs="unbounded">
1558− <complexType>
1559− <attribute name="EndNumber" type="integer" use="optional"/>
1560− <attribute name="Number" type="integer" use="required"/>
1561− </complexType>
1562− </element>
1563− </sequence>
1564− </complexType>
1565− </element>
1566− </sequence>
1567− </complexType>
1568− </element>
1569− </sequence>
1570− </complexType>
1571− </element>
1572− <element name="PostProcessing" minOccurs="0">
1573− <complexType>
1574− <sequence>
1575− <element name="EndTransaction" minOccurs="0">
1576− <annotation>
1577− <documentation>"EndTransaction" is used to end the transaction and finalize the record.</documentation>
1578− </annotation>
1579− <complexType>
1580− <sequence>
1581− <element name="Source">
1582− <complexType>
1583− <attribute name="ReceivedFrom" type="string" use="required">
1584− <annotation>
1585− <documentation>"ReceivedFrom" is used to receive the record.</documentation>
1586− </annotation>
1587− </attribute>
1588− </complexType>
1589− </element>
1590− <element name="Email" minOccurs="0">
1591− <annotation>
1592− <documentation>"Email" is used to send an email notification upon end transaction to any email addresses contained within the particular record.</documentation>
1593− </annotation>
1594− <complexType>
1595− <sequence>
1596− <element name="eTicket" minOccurs="0">
1597− <annotation>
1598− <documentation>"eTicket" is used to send an email notification containing a text-based copy of the eTicket, cannot combine with .../Invoice, or .../Itinerary..</documentation>
1599− </annotation>
1600− <complexType>
1601− <sequence>
1602− <element name="PDF" minOccurs="0">
1603− <complexType>
1604− <attribute name="Ind" type="boolean" use="required"/>
1605− </complexType>
1606− </element>
1607− </sequence>
1608− <attribute name="Ind" type="boolean" use="required"/>
1609− </complexType>
1610− </element>
1611− <element name="Invoice" minOccurs="0">
1612− <annotation>
1613− <documentation>"Invoice" is used to send an email notification containing a text-based copy of the invoice. Invoice cannot combine with .../eTicket, or .../Itinerary.</documentation>
1614− </annotation>
1615− <complexType>
1616− <attribute name="Ind" type="boolean" use="required"/>
1617− </complexType>
1618− </element>
1619− <element name="Itinerary" minOccurs="0">
1620− <annotation>
1621− <documentation>"Itinerary" is used to send an email notification containing a text-based copy of the itinerary. Itinerary cannot combine with .../eTicket, or .../Invoice.</documentation>
1622− </annotation>
1623− <complexType>
1624− <sequence>
1625− <element name="PDF" minOccurs="0">
1626− <annotation>
1627− <documentation>"PDF" is used to send an email notification containing a PDF-based copy of the itinerary.</documentation>
1628− </annotation>
1629− <complexType>
1630− <attribute name="Ind" type="boolean" use="required"/>
1631− </complexType>
1632− </element>
1633− <element name="Segment" minOccurs="0" maxOccurs="unbounded">
1634− <complexType>
1635− <attribute name="EndNumber" type="integer" use="optional">
1636− <annotation>
1637− <documentation>"EndNumber" is used to specify an ending segment in the range to include in the email message.</documentation>
1638− </annotation>
1639− </attribute>
1640− <attribute name="Number" type="integer" use="required">
1641− <annotation>
1642− <documentation>"Number" is used to specify a segment number to include in the email message.</documentation>
1643− </annotation>
1644− </attribute>
1645− </complexType>
1646− </element>
1647− </sequence>
1648− <attribute name="Ind" type="boolean" use="required"/>
1649− </complexType>
1650− </element>
1651− <element name="PersonName" minOccurs="0">
1652− <complexType>
1653− <attribute name="NameNumber" type="string" use="required">
1654− <annotation>
1655− <documentation>"NameNumber" is used to specify a particular passenger name number to send the email notification to. Please note that the email address in the PNR's email field must be name associated to the specified name number.</documentation>
1656− </annotation>
1657− </attribute>
1658− </complexType>
1659− </element>
1660− </sequence>
1661− <attribute name="Ind" type="boolean" use="required"/>
1662− </complexType>
1663− </element>
1664− </sequence>
1665− </complexType>
1666− </element>
1667− </sequence>
1668− <attribute name="acceptNegotiatedFare" type="boolean" use="optional">
1669− <annotation>
1670− <documentation>"acceptNegotiatedFare" is used to accept a negotiated fare when it is not possible to ticket the stored fare.</documentation>
1671− </annotation>
1672− </attribute>
1673− <attribute name="acceptPriceChanges" type="boolean" use="optional">
1674− <annotation>
1675− <documentation>"acceptPriceChanges" is used to specify that system should issue a ticket even if price increases while processing.</documentation>
1676− </annotation>
1677− </attribute>
1678− <attribute name="actionOnPQExpired" use="optional">
1679− <annotation>
1680− <documentation>"actionOnPQExpired" is used to specify appropriate action when Price Quote expires. Available options are "R" - reprice, "Q" Quit, "O" Override.</documentation>
1681− </annotation>
1682− <simpleType>
1683− <restriction base="string">
1684− <enumeration value="O"/>
1685− <enumeration value="Q"/>
1686− <enumeration value="R"/>
1687− </restriction>
1688− </simpleType>
1689− </attribute>
1690− </complexType>
1691− </element>
1692− </sequence>
1693− <attribute name="targetCity" type="string" use="optional">
1694− <annotation>
1695− <documentation>"TargetCity" is used to specify to which city service should change context using ContextChange (AAA) and the rest of the service uses new security. If empty or equals current city the context doesn't change.</documentation>
1696− </annotation>
1697− </attribute>
1698− </extension>
1699− </complexContent>
1700− </complexType>
1701− </element>
1702−</schema>
test/fixtures/retrieve_seat_map.xmldeleted−600
@@ -1,600 +0,0 @@
1−<?xml version="1.0" encoding="UTF-8"?>
2−<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" targetNamespace="http://xml.amadeus.com/SMPREQ_13_1_IA" xmlns="http://xml.amadeus.com/SMPREQ_13_1_IA" elementFormDefault="qualified">
3− <xs:element name="Air_RetrieveSeatMap">
4− <xs:annotation>
5− <xs:documentation xml:lang="en">To request seat map information for a specific flight and date.</xs:documentation>
6− </xs:annotation>
7− <xs:complexType>
8− <xs:sequence>
9− <xs:element name="travelProductIdent" type="TravelProductInformationTypeI">
10− <xs:annotation>
11− <xs:documentation xml:lang="en">Travel Product Identification</xs:documentation>
12− </xs:annotation>
13− </xs:element>
14− <xs:element name="seatRequestParameters" minOccurs="0" type="SeatRequestParametersTypeI">
15− <xs:annotation>
16− <xs:documentation xml:lang="en">Seat Request Parameters</xs:documentation>
17− </xs:annotation>
18− </xs:element>
19− <xs:element name="productInformation" minOccurs="0" type="RelatedProductInformationTypeI" />
20− <xs:element name="frequentTravelerInfo" minOccurs="0" type="FrequentTravellerInformationTypeI">
21− <xs:annotation>
22− <xs:documentation xml:lang="en">Frequent Traveler Information</xs:documentation>
23− </xs:annotation>
24− </xs:element>
25− <xs:element name="resControlInfo" minOccurs="0" type="ReservationControlInformationTypeI">
26− <xs:annotation>
27− <xs:documentation xml:lang="en">Record locator details</xs:documentation>
28− </xs:annotation>
29− </xs:element>
30− <xs:element name="equipmentInformation" minOccurs="0" type="EquipmentInfoTypeI" />
31− <xs:element name="additionalInfo" minOccurs="0" type="AdditionalBusinessSourceInformationTypeI">
32− <xs:annotation>
33− <xs:documentation xml:lang="en">Point of Sell override</xs:documentation>
34− </xs:annotation>
35− </xs:element>
36− <xs:element name="conversionRate" minOccurs="0" type="ConversionRateTypeI">
37− <xs:annotation>
38− <xs:documentation xml:lang="en">To return price in another currency</xs:documentation>
39− </xs:annotation>
40− </xs:element>
41− <xs:element name="traveler" minOccurs="0" maxOccurs="99">
42− <xs:annotation>
43− <xs:documentation xml:lang="en">Traveler detail group</xs:documentation>
44− </xs:annotation>
45− <xs:complexType>
46− <xs:sequence>
47− <xs:element name="travelerInformation" type="TravellerInformationTypeI" />
48− <xs:element name="frequentTravelerDetails" minOccurs="0" maxOccurs="99" type="FrequentTravellerInformationTypeI" />
49− <xs:element name="fareInfo" minOccurs="0" type="FareInformationTypeI">
50− <xs:annotation>
51− <xs:documentation xml:lang="en">PTC override and Ticket Designator</xs:documentation>
52− </xs:annotation>
53− </xs:element>
54− <xs:element name="dateAndTimeInfo" minOccurs="0" type="DateAndTimeInformationTypeI">
55− <xs:annotation>
56− <xs:documentation xml:lang="en">Date of Birth</xs:documentation>
57− </xs:annotation>
58− </xs:element>
59− <xs:element name="ticketDetails" minOccurs="0" type="TicketNumberTypeI">
60− <xs:annotation>
61− <xs:documentation xml:lang="en">eTicket number for pricing override</xs:documentation>
62− </xs:annotation>
63− </xs:element>
64− <xs:element name="fareQualifierDetails" minOccurs="0" type="FareQualifierDetailsTypeI">
65− <xs:annotation>
66− <xs:documentation xml:lang="en">Fare Basis</xs:documentation>
67− </xs:annotation>
68− </xs:element>
69− </xs:sequence>
70− </xs:complexType>
71− </xs:element>
72− </xs:sequence>
73− </xs:complexType>
74− </xs:element>
75− <xs:complexType name="AdditionalBusinessSourceInformationTypeI">
76− <xs:annotation>
77− <xs:documentation xml:lang="en">To specify additional originator and source information.</xs:documentation>
78− </xs:annotation>
79− <xs:sequence>
80− <xs:element name="sourceType" type="SourceTypeDetailsTypeI" />
81− <xs:element name="originatorDetails" minOccurs="0" type="OriginatorIdentificationDetailsTypeI" />
82− <xs:element name="locationDetails" minOccurs="0" type="LocationTypeI" />
83− <xs:element name="countryCode" minOccurs="0" type="AlphaNumericString_Length1To3" />
84− <xs:element name="systemCode" minOccurs="0" type="AlphaNumericString_Length1To35" />
85− </xs:sequence>
86− </xs:complexType>
87− <xs:complexType name="AdditionalEquipmentInformationTypeI">
88− <xs:annotation>
89− <xs:documentation xml:lang="en">To identify equipment configuration, registration number, and cabin facilities.</xs:documentation>
90− </xs:annotation>
91− <xs:sequence>
92− <xs:element name="fittedConfigurationCode" minOccurs="0" type="AlphaNumericString_Length1To12" />
93− <xs:element name="defaultConfigurationCode" minOccurs="0" type="AlphaNumericString_Length1To12" />
94− <xs:element name="airlineDetails" minOccurs="0" type="AlphaNumericString_Length1To35" />
95− <xs:element name="code" minOccurs="0" type="AlphaNumericString_Length1To17" />
96− <xs:element name="characteristic" minOccurs="0" maxOccurs="2" type="AlphaNumericString_Length1To3" />
97− </xs:sequence>
98− </xs:complexType>
99− <xs:complexType name="AdditionalFareQualifierDetailsTypeI">
100− <xs:annotation>
101− <xs:documentation xml:lang="en">To specify the fare basis and ticket designator codes.</xs:documentation>
102− </xs:annotation>
103− <xs:sequence>
104− <xs:element name="rateClass" minOccurs="0" type="AlphaNumericString_Length1To35" />
105− <xs:element name="commodityCategory" minOccurs="0" type="AlphaNumericString_Length1To18" />
106− </xs:sequence>
107− </xs:complexType>
108− <xs:complexType name="CompanyIdentificationTypeI">
109− <xs:annotation>
110− <xs:documentation xml:lang="en">Code or name to identify a company and any associated companies.</xs:documentation>
111− </xs:annotation>
112− <xs:sequence>
113− <xs:element name="marketingCompany" minOccurs="0" type="AlphaNumericString_Length1To35" />
114− <xs:element name="operatingCompany" minOccurs="0" type="AlphaNumericString_Length1To35" />
115− </xs:sequence>
116− </xs:complexType>
117− <xs:complexType name="ConfigurationDetailsTypeI">
118− <xs:annotation>
119− <xs:documentation xml:lang="en">To identify the number of seats for a specific class of service.</xs:documentation>
120− </xs:annotation>
121− <xs:sequence>
122− <xs:element name="classDesignator" type="AlphaString_Length1To1" />
123− <xs:element name="numberOfSeats" minOccurs="0" type="NumericInteger_Length1To3" />
124− <xs:element name="characteristic" minOccurs="0" maxOccurs="26" type="AlphaNumericString_Length1To17" />
125− </xs:sequence>
126− </xs:complexType>
127− <xs:complexType name="ConversionRateDetailsTypeI">
128− <xs:annotation>
129− <xs:documentation xml:lang="en">To specify the conversion rate and the monetary amount.</xs:documentation>
130− </xs:annotation>
131− <xs:sequence>
132− <xs:element name="conversionType" minOccurs="0" type="AlphaNumericString_Length1To3" />
133− <xs:element name="currency" minOccurs="0" type="AlphaNumericString_Length1To3" />
134− </xs:sequence>
135− </xs:complexType>
136− <xs:complexType name="ConversionRateTypeI">
137− <xs:annotation>
138− <xs:documentation xml:lang="en">To specify details of a conversion rate related to an amount.</xs:documentation>
139− </xs:annotation>
140− <xs:sequence>
141− <xs:element name="conversionRateDetails" type="ConversionRateDetailsTypeI" />
142− </xs:sequence>
143− </xs:complexType>
144− <xs:complexType name="DateAndTimeDetailsTypeI">
145− <xs:annotation>
146− <xs:documentation xml:lang="en">To provide date and time details relative to flight movements.</xs:documentation>
147− </xs:annotation>
148− <xs:sequence>
149− <xs:element name="qualifier" minOccurs="0" type="AlphaNumericString_Length1To3" />
150− <xs:element name="date" minOccurs="0" type="AlphaNumericString_Length1To35" />
151− </xs:sequence>
152− </xs:complexType>
153− <xs:complexType name="DateAndTimeInformationTypeI">
154− <xs:annotation>
155− <xs:documentation xml:lang="en">To provide date and time details relative to flight movements.</xs:documentation>
156− </xs:annotation>
157− <xs:sequence>
158− <xs:element name="dateAndTimeDetails" minOccurs="0" maxOccurs="99" type="DateAndTimeDetailsTypeI" />
159− </xs:sequence>
160− </xs:complexType>
161− <xs:complexType name="EquipmentInfoTypeI">
162− <xs:annotation>
163− <xs:documentation xml:lang="en">To specify configuration details of an aircraft.</xs:documentation>
164− </xs:annotation>
165− <xs:sequence>
166− <xs:element name="cabinClassDetails" minOccurs="0" maxOccurs="5" type="ConfigurationDetailsTypeI" />
167− <xs:element name="iataAircraftTypeCode" minOccurs="0" type="AlphaNumericString_Length1To8" />
168− <xs:element name="configVersionDetails" minOccurs="0" type="AdditionalEquipmentInformationTypeI" />
169− <xs:element name="configVersionDescription" minOccurs="0" type="AlphaNumericString_Length1To70" />
170− </xs:sequence>
171− </xs:complexType>
172− <xs:complexType name="FareInformationTypeI">
173− <xs:annotation>
174− <xs:documentation xml:lang="en">To specify fare details.</xs:documentation>
175− </xs:annotation>
176− <xs:sequence>
177− <xs:element name="valueQualifier" minOccurs="0" type="AlphaNumericString_Length1To3" />
178− <xs:element name="rateCategory" minOccurs="0" maxOccurs="9" type="AlphaNumericString_Length1To35" />
179− </xs:sequence>
180− </xs:complexType>
181− <xs:complexType name="FareQualifierDetailsTypeI">
182− <xs:annotation>
183− <xs:documentation xml:lang="en">To specify the details which qualify a fare</xs:documentation>
184− </xs:annotation>
185− <xs:sequence>
186− <xs:element name="additionalFareDetails" minOccurs="0" type="AdditionalFareQualifierDetailsTypeI" />
187− </xs:sequence>
188− </xs:complexType>
189− <xs:complexType name="FrequentTravellerIdentificationTypeI">
190− <xs:annotation>
191− <xs:documentation xml:lang="en">Identification of the frequent traveller number by company code with the capability to reference a specific traveller.</xs:documentation>
192− </xs:annotation>
193− <xs:sequence>
194− <xs:element name="carrier" type="AlphaNumericString_Length1To35" />
195− <xs:element name="number" type="AlphaNumericString_Length1To25" />
196− <xs:element name="customerReference" minOccurs="0" type="AlphaNumericString_Length1To10" />
197− <xs:element name="tierLevel" minOccurs="0" type="AlphaNumericString_Length1To35" />
198− <xs:element name="priorityCode" minOccurs="0" type="AlphaNumericString_Length1To12" />
199− <xs:element name="customerValue" minOccurs="0" type="NumericInteger_Length1To4" />
200− <xs:element name="type" minOccurs="0" type="AlphaNumericString_Length1To3">
201− <xs:annotation>
202− <xs:documentation xml:lang="en">To specify the product/account number qualifier. (e.g. 2=Corporate Frequent Flyer).</xs:documentation>
203− </xs:annotation>
204− </xs:element>
205− </xs:sequence>
206− </xs:complexType>
207− <xs:complexType name="FrequentTravellerInformationTypeI">
208− <xs:annotation>
209− <xs:documentation xml:lang="en">To specify frequent traveler information.</xs:documentation>
210− </xs:annotation>
211− <xs:sequence>
212− <xs:element name="frequentTravellerDetails" type="FrequentTravellerIdentificationTypeI" />
213− <xs:element name="otherFrequentTravellerDetails" minOccurs="0" maxOccurs="98" type="FrequentTravellerIdentificationTypeI" />
214− </xs:sequence>
215− </xs:complexType>
216− <xs:complexType name="GenericDetailsTypeI">
217− <xs:annotation>
218− <xs:documentation xml:lang="en">To identify the type of seat requested.</xs:documentation>
219− </xs:annotation>
220− <xs:sequence>
221− <xs:element name="cabinClassDesignator" minOccurs="0" type="AlphaString_Length1To1" />
222− <xs:element name="noSmokingIndicator" minOccurs="0" type="AlphaString_Length1To1" />
223− <xs:element name="cabinClass" minOccurs="0" type="NumericInteger_Length1To1" />
224− <xs:element name="compartmentDesignator" minOccurs="0" type="AlphaString_Length1To1" />
225− <xs:element name="seatCharacteristic" minOccurs="0" maxOccurs="5" type="AMA_EDICodesetType_Length1to2" />
226− </xs:sequence>
227− </xs:complexType>
228− <xs:complexType name="LocationTypeI">
229− <xs:annotation>
230− <xs:documentation xml:lang="en">To identify a location by code or name.</xs:documentation>
231− </xs:annotation>
232− <xs:sequence>
233− <xs:element name="trueLocationId" minOccurs="0" type="AlphaNumericString_Length1To25" />
234− <xs:element name="trueLocation" minOccurs="0" type="AlphaNumericString_Length1To17" />
235− </xs:sequence>
236− </xs:complexType>
237− <xs:complexType name="OriginatorIdentificationDetailsTypeI">
238− <xs:annotation>
239− <xs:documentation xml:lang="en">To identify the originator of the travel request.</xs:documentation>
240− </xs:annotation>
241− <xs:sequence>
242− <xs:element name="originatorId" minOccurs="0" type="NumericInteger_Length1To9">
243− <xs:annotation>
244− <xs:documentation xml:lang="en">is alpanum since the sine of an agent might contain his initials and duty code</xs:documentation>
245− </xs:annotation>
246− </xs:element>
247− <xs:element name="inHouseIdentification1" minOccurs="0" type="AlphaNumericString_Length1To9" />
248− <xs:element name="inHouseIdentification2" minOccurs="0" type="AlphaNumericString_Length1To9" />
249− <xs:element name="inHouseIdentification3" minOccurs="0" type="AlphaNumericString_Length1To9" />
250− </xs:sequence>
251− </xs:complexType>
252− <xs:complexType name="ProductDateTimeTypeI">
253− <xs:annotation>
254− <xs:documentation xml:lang="en">To specify the dates and times associated with a product.</xs:documentation>
255− </xs:annotation>
256− <xs:sequence>
257− <xs:element name="departureDate" minOccurs="0" type="AlphaNumericString_Length1To35" />
258− <xs:element name="departureTime" minOccurs="0" type="Time24_HHMM" />
259− <xs:element name="arrivalDate" minOccurs="0" type="AlphaNumericString_Length1To35" />
260− <xs:element name="arrivalTime" minOccurs="0" type="Time24_HHMM" />
261− <xs:element name="dateVariation" minOccurs="0" type="NumericInteger_Length1To1" />
262− </xs:sequence>
263− </xs:complexType>
264− <xs:complexType name="ProductIdentificationDetailsTypeI">
265− <xs:annotation>
266− <xs:documentation xml:lang="en">Code, number or name to identify a specific product or service.</xs:documentation>
267− </xs:annotation>
268− <xs:sequence>
269− <xs:element name="flightNumber" type="AlphaNumericString_Length1To35" />
270− <xs:element name="bookingClass" minOccurs="0" type="AlphaNumericString_Length1To17" />
271− <xs:element name="operationalSuffix" minOccurs="0" type="AlphaNumericString_Length1To3" />
272− <xs:element name="modifier" minOccurs="0" maxOccurs="3" type="AlphaNumericString_Length1To7" />
273− </xs:sequence>
274− </xs:complexType>
275− <xs:complexType name="ProductTypeDetailsTypeI">
276− <xs:annotation>
277− <xs:documentation xml:lang="en">To specify additional characteristics of a product or service.</xs:documentation>
278− </xs:annotation>
279− <xs:sequence>
280− <xs:element name="flightIndicator" maxOccurs="9" type="AlphaNumericString_Length1To6" />
281− </xs:sequence>
282− </xs:complexType>
283− <xs:complexType name="RangeOfRowsDetailsTypeI">
284− <xs:annotation>
285− <xs:documentation xml:lang="en">To specify row information for a means of transport.</xs:documentation>
286− </xs:annotation>
287− <xs:sequence>
288− <xs:element name="seatRowNumber" type="NumericInteger_Length1To3" />
289− <xs:element name="numberOfRows" minOccurs="0" type="NumericInteger_Length1To3" />
290− <xs:element name="seatColumn" minOccurs="0" maxOccurs="20" type="AlphaNumericString_Length1To1" />
291− </xs:sequence>
292− </xs:complexType>
293− <xs:complexType name="RelatedProductInformationTypeI">
294− <xs:annotation>
295− <xs:documentation xml:lang="en">To indicate quantity and action required in relation to a product.</xs:documentation>
296− </xs:annotation>
297− <xs:sequence>
298− <xs:element name="quantity" minOccurs="0" type="NumericInteger_Length1To15" />
299− <xs:element name="statusCode" minOccurs="0" maxOccurs="10" type="AlphaNumericString_Length1To3" />
300− </xs:sequence>
301− </xs:complexType>
302− <xs:complexType name="ReservationControlInformationDetailsTypeI">
303− <xs:annotation>
304− <xs:documentation xml:lang="en">To specify the information required to identify a reservation.</xs:documentation>
305− </xs:annotation>
306− <xs:sequence>
307− <xs:element name="companyId" minOccurs="0" type="AlphaNumericString_Length1To35" />
308− <xs:element name="controlNumber" minOccurs="0" type="AlphaNumericString_Length1To20" />
309− <xs:element name="controlType" minOccurs="0" type="AlphaNumericString_Length1To1" />
310− <xs:element name="date" minOccurs="0" type="AlphaNumericString_Length1To35" />
311− <xs:element name="time" minOccurs="0" type="NumericInteger_Length1To9" />
312− </xs:sequence>
313− </xs:complexType>
314− <xs:complexType name="ReservationControlInformationTypeI">
315− <xs:annotation>
316− <xs:documentation xml:lang="en">To specify a reference to a reservation.</xs:documentation>
317− </xs:annotation>
318− <xs:sequence>
319− <xs:element name="reservation" minOccurs="0" maxOccurs="9" type="ReservationControlInformationDetailsTypeI" />
320− </xs:sequence>
321− </xs:complexType>
322− <xs:complexType name="SeatRequestParametersTypeI">
323− <xs:annotation>
324− <xs:documentation xml:lang="en">To specify the selection criteria for a seat map request.</xs:documentation>
325− </xs:annotation>
326− <xs:sequence>
327− <xs:element name="genericDetails" minOccurs="0" type="GenericDetailsTypeI" />
328− <xs:element name="rangeOfRowsDetails" minOccurs="0" type="RangeOfRowsDetailsTypeI" />
329− <xs:element name="processingIndicator" minOccurs="0" type="AlphaNumericString_Length1To3" />
330− <xs:element name="referenceNumber" minOccurs="0" type="AlphaNumericString_Length1To35" />
331− <xs:element name="description" minOccurs="0" type="AlphaNumericString_Length1To70" />
332− </xs:sequence>
333− </xs:complexType>
334− <xs:complexType name="SourceTypeDetailsTypeI">
335− <xs:annotation>
336− <xs:documentation xml:lang="en">To identify the type of source.</xs:documentation>
337− </xs:annotation>
338− <xs:sequence>
339− <xs:element name="sourceQualifier1" type="AlphaNumericString_Length1To3" />
340− <xs:element name="sourceQualifier2" minOccurs="0" type="AlphaNumericString_Length1To3" />
341− </xs:sequence>
342− </xs:complexType>
343− <xs:complexType name="TicketNumberDetailsTypeI">
344− <xs:annotation>
345− <xs:documentation xml:lang="en">To specify a ticket number, type of ticket, and related information.</xs:documentation>
346− </xs:annotation>
347− <xs:sequence>
348− <xs:element name="number" minOccurs="0" type="AlphaNumericString_Length1To35" />
349− </xs:sequence>
350− </xs:complexType>
351− <xs:complexType name="TicketNumberTypeI">
352− <xs:annotation>
353− <xs:documentation xml:lang="en">To convey information related to a specific ticket.</xs:documentation>
354− </xs:annotation>
355− <xs:sequence>
356− <xs:element name="documentDetails" type="TicketNumberDetailsTypeI" />
357− </xs:sequence>
358− </xs:complexType>
359− <xs:complexType name="TravelProductInformationTypeI">
360− <xs:annotation>
361− <xs:documentation xml:lang="en">To specify details related to a product.</xs:documentation>
362− </xs:annotation>
363− <xs:sequence>
364− <xs:element name="flightDate" minOccurs="0" type="ProductDateTimeTypeI" />
365− <xs:element name="boardPointDetails" minOccurs="0" type="LocationTypeI" />
366− <xs:element name="offpointDetails" minOccurs="0" type="LocationTypeI" />
367− <xs:element name="companyDetails" minOccurs="0" type="CompanyIdentificationTypeI" />
368− <xs:element name="flightIdentification" minOccurs="0" type="ProductIdentificationDetailsTypeI" />
369− <xs:element name="flightTypeDetails" minOccurs="0" type="ProductTypeDetailsTypeI" />
370− </xs:sequence>
371− </xs:complexType>
372− <xs:complexType name="TravellerDetailsTypeI">
373− <xs:annotation>
374− <xs:documentation xml:lang="en">To identify the given/first name and the title of a traveller and the traveller type.</xs:documentation>
375− </xs:annotation>
376− <xs:sequence>
377− <xs:element name="givenName" minOccurs="0" type="AlphaNumericString_Length1To70" />
378− <xs:element name="type" minOccurs="0" type="AlphaNumericString_Length1To3" />
379− <xs:element name="uniqueCustomerIdentifier" minOccurs="0" type="AlphaNumericString_Length1To10" />
380− <xs:element name="infantIndicator" minOccurs="0" type="AlphaNumericString_Length1To1" />
381− </xs:sequence>
382− </xs:complexType>
383− <xs:complexType name="TravellerInformationTypeI">
384− <xs:annotation>
385− <xs:documentation xml:lang="en">To specify a traveler(s) and personal details relating to the traveler(s).</xs:documentation>
386− </xs:annotation>
387− <xs:sequence>
388− <xs:element name="paxDetails" type="TravellerSurnameInformationTypeI" />
389− <xs:element name="otherPaxDetails" minOccurs="0" maxOccurs="99" type="TravellerDetailsTypeI" />
390− </xs:sequence>
391− </xs:complexType>
392− <xs:complexType name="TravellerSurnameInformationTypeI">
393− <xs:annotation>
394− <xs:documentation xml:lang="en">Identification of the surname of a traveller, the type of traveller, number of travellers per surname and the action to be taken.</xs:documentation>
395− </xs:annotation>
396− <xs:sequence>
397− <xs:element name="surname" type="AlphaNumericString_Length1To70" />
398− <xs:element name="type" minOccurs="0" type="AlphaNumericString_Length1To3" />
399− <xs:element name="quantity" minOccurs="0" type="NumericInteger_Length1To15" />
400− </xs:sequence>
401− </xs:complexType>
402− <xs:simpleType name="AlphaNumericString_Length1To3">
403− <xs:annotation>
404− <xs:documentation xml:lang="en">Format limitations: an..3</xs:documentation>
405− </xs:annotation>
406− <xs:restriction base="xs:string">
407− <xs:minLength value="1" />
408− <xs:maxLength value="3" />
409− </xs:restriction>
410− </xs:simpleType>
411− <xs:simpleType name="AlphaNumericString_Length1To35">
412− <xs:annotation>
413− <xs:documentation xml:lang="en">Format limitations: an..35</xs:documentation>
414− </xs:annotation>
415− <xs:restriction base="xs:string">
416− <xs:minLength value="1" />
417− <xs:maxLength value="35" />
418− </xs:restriction>
419− </xs:simpleType>
420− <xs:simpleType name="AlphaNumericString_Length1To70">
421− <xs:annotation>
422− <xs:documentation xml:lang="en">Format limitations: an..70</xs:documentation>
423− </xs:annotation>
424− <xs:restriction base="xs:string">
425− <xs:minLength value="1" />
426− <xs:maxLength value="70" />
427− </xs:restriction>
428− </xs:simpleType>
429− <xs:simpleType name="NumericInteger_Length1To15">
430− <xs:annotation>
431− <xs:documentation xml:lang="en">Format limitations: n..15</xs:documentation>
432− </xs:annotation>
433− <xs:restriction base="xs:integer">
434− <xs:pattern value="-?[0-9]{1,15}" />
435− </xs:restriction>
436− </xs:simpleType>
437− <xs:simpleType name="AlphaNumericString_Length1To8">
438− <xs:annotation>
439− <xs:documentation xml:lang="en">Format limitations: an..8</xs:documentation>
440− </xs:annotation>
441− <xs:restriction base="xs:string">
442− <xs:minLength value="1" />
443− <xs:maxLength value="8" />
444− </xs:restriction>
445− </xs:simpleType>
446− <xs:simpleType name="NumericInteger_Length1To1">
447− <xs:annotation>
448− <xs:documentation xml:lang="en">Format limitations: n1</xs:documentation>
449− </xs:annotation>
450− <xs:restriction base="xs:integer">
451− <xs:pattern value="-?[0-9]{1,1}" />
452− </xs:restriction>
453− </xs:simpleType>
454− <xs:simpleType name="AlphaNumericString_Length1To25">
455− <xs:annotation>
456− <xs:documentation xml:lang="en">Format limitations: an..25</xs:documentation>
457− </xs:annotation>
458− <xs:restriction base="xs:string">
459− <xs:minLength value="1" />
460− <xs:maxLength value="25" />
461− </xs:restriction>
462− </xs:simpleType>
463− <xs:simpleType name="AlphaNumericString_Length1To17">
464− <xs:annotation>
465− <xs:documentation xml:lang="en">Format limitations: an..17</xs:documentation>
466− </xs:annotation>
467− <xs:restriction base="xs:string">
468− <xs:minLength value="1" />
469− <xs:maxLength value="17" />
470− </xs:restriction>
471− </xs:simpleType>
472− <xs:simpleType name="AlphaNumericString_Length1To7">
473− <xs:annotation>
474− <xs:documentation xml:lang="en">Format limitations: an..7</xs:documentation>
475− </xs:annotation>
476− <xs:restriction base="xs:string">
477− <xs:minLength value="1" />
478− <xs:maxLength value="7" />
479− </xs:restriction>
480− </xs:simpleType>
481− <xs:simpleType name="AlphaNumericString_Length1To6">
482− <xs:annotation>
483− <xs:documentation xml:lang="en">Format limitations: an..6</xs:documentation>
484− </xs:annotation>
485− <xs:restriction base="xs:string">
486− <xs:minLength value="1" />
487− <xs:maxLength value="6" />
488− </xs:restriction>
489− </xs:simpleType>
490− <xs:simpleType name="AlphaString_Length1To1">
491− <xs:annotation>
492− <xs:documentation xml:lang="en">Format limitations: a1</xs:documentation>
493− </xs:annotation>
494− <xs:restriction base="xs:string">
495− <xs:minLength value="1" />
496− <xs:maxLength value="1" />
497− </xs:restriction>
498− </xs:simpleType>
499− <xs:simpleType name="NumericInteger_Length1To3">
500− <xs:annotation>
501− <xs:documentation xml:lang="en">Format limitations: n..3</xs:documentation>
502− </xs:annotation>
503− <xs:restriction base="xs:integer">
504− <xs:pattern value="-?[0-9]{1,3}" />
505− </xs:restriction>
506− </xs:simpleType>
507− <xs:simpleType name="AlphaNumericString_Length1To1">
508− <xs:annotation>
509− <xs:documentation xml:lang="en">Format limitations: an1</xs:documentation>
510− </xs:annotation>
511− <xs:restriction base="xs:string">
512− <xs:minLength value="1" />
513− <xs:maxLength value="1" />
514− </xs:restriction>
515− </xs:simpleType>
516− <xs:simpleType name="AlphaNumericString_Length1To10">
517− <xs:annotation>
518− <xs:documentation xml:lang="en">Format limitations: an..10</xs:documentation>
519− </xs:annotation>
520− <xs:restriction base="xs:string">
521− <xs:minLength value="1" />
522− <xs:maxLength value="10" />
523− </xs:restriction>
524− </xs:simpleType>
525− <xs:simpleType name="AlphaNumericString_Length1To12">
526− <xs:annotation>
527− <xs:documentation xml:lang="en">Format limitations: an..12</xs:documentation>
528− </xs:annotation>
529− <xs:restriction base="xs:string">
530− <xs:minLength value="1" />
531− <xs:maxLength value="12" />
532− </xs:restriction>
533− </xs:simpleType>
534− <xs:simpleType name="NumericInteger_Length1To4">
535− <xs:annotation>
536− <xs:documentation xml:lang="en">Format limitations: n..4</xs:documentation>
537− </xs:annotation>
538− <xs:restriction base="xs:integer">
539− <xs:pattern value="-?[0-9]{1,4}" />
540− </xs:restriction>
541− </xs:simpleType>
542− <xs:simpleType name="AlphaNumericString_Length1To20">
543− <xs:annotation>
544− <xs:documentation xml:lang="en">Format limitations: an..20</xs:documentation>
545− </xs:annotation>
546− <xs:restriction base="xs:string">
547− <xs:minLength value="1" />
548− <xs:maxLength value="20" />
549− </xs:restriction>
550− </xs:simpleType>
551− <xs:simpleType name="NumericInteger_Length1To9">
552− <xs:annotation>
553− <xs:documentation xml:lang="en">Format limitations: n..9</xs:documentation>
554− </xs:annotation>
555− <xs:restriction base="xs:integer">
556− <xs:pattern value="-?[0-9]{1,9}" />
557− </xs:restriction>
558− </xs:simpleType>
559− <xs:simpleType name="AlphaNumericString_Length1To9">
560− <xs:annotation>
561− <xs:documentation xml:lang="en">Format limitations: an..9</xs:documentation>
562− </xs:annotation>
563− <xs:restriction base="xs:string">
564− <xs:minLength value="1" />
565− <xs:maxLength value="9" />
566− </xs:restriction>
567− </xs:simpleType>
568− <xs:simpleType name="AlphaNumericString_Length1To18">
569− <xs:annotation>
570− <xs:documentation xml:lang="en">Format limitations: an..18</xs:documentation>
571− </xs:annotation>
572− <xs:restriction base="xs:string">
573− <xs:minLength value="1" />
574− <xs:maxLength value="18" />
575− </xs:restriction>
576− </xs:simpleType>
577− <xs:simpleType name="AMA_EDICodesetType_Length1to2">
578− <xs:annotation>
579− <xs:documentation xml:lang="en">Used for codes in the AMADEUS code tables. Code Length is two alphanumeric characters.</xs:documentation>
580− </xs:annotation>
581− <xs:restriction base="xs:string">
582− <xs:pattern value="[0-9A-Z]{1,2}" />
583− </xs:restriction>
584− </xs:simpleType>
585− <xs:simpleType name="Time24_HHMM">
586− <xs:annotation>
587− <xs:documentation xml:lang="en">Time format: 24H. All digits are mandatory . Example: from 0000 to 2359</xs:documentation>
588− </xs:annotation>
589− <xs:restriction base="xs:string">
590− <xs:pattern value="([0-1][0-9]|2[0-3])[0-5][0-9]" />
591− </xs:restriction>
592− </xs:simpleType>
593−</xs:schema>
594−<!-- SchemaRules="2010/01"-->
595−<!--Created with SchemaBuilder 5.1.0 by Amadeus S.A.S.-->
596−<!--"Amadeus Proprietary and Confidential Information: unauthorized use and disclosure strictly forbidden. 2010 - Amadeus s.a.s - All Rights Reserved."-->
597−<!--Build Key:
598−1F8B080000000000000095534D6FDB4610BDEFAF58E49243218A8A8BA411B007C6A25D0395ED48CC4D8030E68EA44596BBECCED23063F8BF7796A46A1728D0F442CCC7723EDE7B735DDE969BA22A57FBBB5BF5215FFC3A5B2C661F72599DBA401A7A997F5E5EE4CBC52779BDAE7EC9F3659E8B625DC4BE45BA32161D34A838B0FF0264EA2A85B327D2E201086F39472DD4A84E31B6CBF9FCA9B11934A0B1A3ACF6CD5C3C744E5B5C99A0E684311A77A4B9363589FA84F5F72D7F1B503174286AAF919F9072DE25AF69D0B137E59A165C9FDA29D759CB81B60FE6788AEA5D31B693F7C1B7C16084D04B705A5E7A77309A6B18B0F2C61D7C68201AEF96B273D0C5930FE6076AD9110ECFB5A1DA7AEA024A8AC1D4D1F692FF79309A6B649281CBE54C9E9B51061925DF5AB9497390DCF0F4E11175F64E683C4067E37568135C5A1DC0120AEDBB078B5BFCB34357E33DC4FA3465D07DF92930D1BDBE794E04BDEC9F1F31106FC556408B5C862D387287FE451C98BE4D6719339F981CFC81CEE1E764FD4701EB6BB013E4D61F35D3B85AEE7E2F8BD5AED4E60075ACBCB7B42BABFDCA5004172F9929E68F99DBAD217CC7C4F8F88606AE69F7873F722D771C0631FACED95E34188E388131D85706ADA6AD0FF16FF87871E2B90A4A98FE33B662D68D9D94E3FE1744AD372EDE621CE918C416BC8F6F101AFC24E04C8C2B2444295D523ECF17538CAE7C28ACE1DA936293164C8DB46225716F16E58822351062AAFBCD99DAC47E5A24067064077D323E8AB1A6F954B92AD6F3678DD6F01AC0027AC9382BD278FAEDF9B0582ECF3733D6E4C800D570C9C6D5E2896CBCEB62DBC52B6F3506950242CC66EB11C6F724CDEB9DCC66620449DD14E24D7F55DC17FBC284FDE2E2236BBA01E3D4F6A612F8D4325D7BA0FDAABC56D5E65B79A647424050BF5D9C7DB55DDF6FCAAFA2E57B3074628647DC4772D482AD47931863730006060C556ABA413E4E7CE43382B886569C69FAD7E444BC5A5C88BF00DC744BCF06050000
599−-->
600−
test/fixtures/simple.xsddeleted−18
@@ -1,18 +0,0 @@
1−<?xml version="1.0"?>
2−<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
3−targetNamespace="https://www.w3schools.com"
4−xmlns="https://www.w3schools.com"
5−elementFormDefault="qualified">
6−
7−<xs:element name="note">
8− <xs:complexType>
9− <xs:sequence>
10− <xs:element name="to" type="xs:string"/>
11− <xs:element name="from" type="xs:string"/>
12− <xs:element name="heading" type="xs:string"/>
13− <xs:element name="body" type="xs:string"/>
14− </xs:sequence>
15− </xs:complexType>
16−</xs:element>
17−
18−</xs:schema>
xsd-parser.cabal+25−20
@@ -18,19 +18,13 @@ extra-source-files: CHANGELOG.md
1818
1919
2020library
21− -- ghc-options: -Werror
2221 -- Modules exported by the library.
23− exposed-modules: Text.XSD
24− , Text.XSD.Parser
25− , Text.XSD.Internal
26−
27− default-extensions: OverloadedStrings
28− , LambdaCase
29− , QuasiQuotes
30− , TemplateHaskell
22+ exposed-modules: Xsd
23+ , Xsd.Types
24+ , Xsd.Parser
3125
3226 -- Other library packages from which modules are imported.
33− build-depends: base ^>=4.12.0.0
27+ build-depends: base >=4.12 && < 5
3428 , bytestring
3529 , containers
3630 , lens >= 4.13
@@ -41,9 +35,14 @@ library
4135 , xml-conduit
4236 , writer-cps-mtl
4337 , uniplate
38+ , network-uri
39+ , http-client
40+ , http-client-tls
41+ , filepath
4442
4543 -- Directories containing source files.
4644 hs-source-dirs: src
45+ ghc-options: -Wall
4746
4847 -- Base language which the package is written in.
4948 default-language: Haskell2010
@@ -52,20 +51,26 @@ test-suite spec
5251 type: exitcode-stdio-1.0
5352 hs-source-dirs: test
5453 main-is: Main.hs
54+ other-modules: Spec
5555 build-depends: base
5656 , bytestring
57+ , text
5758 , hspec
5859 , transformers
5960 , xml-conduit
61+ , containers
62+ , xsd-parser
63+ default-language: Haskell2010
64+ 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
6074 , xsd-parser
6175 default-language: Haskell2010
62− default-extensions: CPP
63− , DeriveGeneric
64− , FlexibleInstances
65− , LambdaCase
66− , OverloadedStrings
67− , StandaloneDeriving
68− , TemplateHaskell
69− , TupleSections
70− , TypeFamilies
71− ghc-options: -Wall -fno-warn-missing-signatures
76+ ghc-options: -Wall
xsdtestsnew file+1

Submodule changed.

xsts-test/Main.hsnew file+201
@@ -0,0 +1,201 @@
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.mdnew file+100
@@ -0,0 +1,100 @@
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