You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

2659 lines
89 KiB

  1. # Copyright (c) 2001 Zope Corporation and Contributors. All Rights Reserved.
  2. #
  3. # This software is subject to the provisions of the Zope Public License,
  4. # Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution.
  5. # THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
  6. # WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  7. # WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
  8. # FOR A PARTICULAR PURPOSE.
  9. ident = "$Id$"
  10. import types, weakref, urllib
  11. from threading import RLock
  12. from xml.dom.ext import SplitQName
  13. from xml.ns import SCHEMA, XMLNS
  14. from Utility import DOM, Collection
  15. from StringIO import StringIO
  16. class SchemaReader:
  17. """A SchemaReader creates XMLSchema objects from urls and xml data.
  18. """
  19. def __init__(self, domReader=None):
  20. """domReader -- class must implement DOMAdapterInterface
  21. """
  22. self.__readerClass = domReader
  23. if not self.__readerClass:
  24. self.__readerClass = DOMAdapter
  25. self._includes = {}
  26. self._imports = {}
  27. def __setImports(self, schema):
  28. """Add dictionary of imports to schema instance.
  29. schema -- XMLSchema instance
  30. """
  31. for ns,val in schema.imports.items():
  32. if self._imports.has_key(ns):
  33. schema.addImportSchema(self._imports[ns])
  34. def __setIncludes(self, schema):
  35. """Add dictionary of includes to schema instance.
  36. schema -- XMLSchema instance
  37. """
  38. for schemaLocation, val in schema.includes.items():
  39. if self._includes.has_key(schemaLocation):
  40. schema.addIncludeSchema(self._imports[schemaLocation])
  41. def addSchemaByLocation(self, location, schema):
  42. """provide reader with schema document for a location.
  43. """
  44. self._includes[location] = schema
  45. def addSchemaByNamespace(self, schema):
  46. """provide reader with schema document for a targetNamespace.
  47. """
  48. self._imports[schema.targetNamespace] = schema
  49. def loadFromNode(self, parent, element):
  50. """element -- DOM node or document
  51. parent -- WSDLAdapter instance
  52. """
  53. reader = self.__readerClass(element)
  54. schema = XMLSchema(parent)
  55. #HACK to keep a reference
  56. schema.wsdl = parent
  57. schema.load(reader)
  58. return schema
  59. def loadFromStream(self, file):
  60. """Return an XMLSchema instance loaded from a file object.
  61. file -- file object
  62. """
  63. reader = self.__readerClass()
  64. reader.loadDocument(file)
  65. schema = XMLSchema()
  66. schema.load(reader)
  67. self.__setIncludes(schema)
  68. self.__setImports(schema)
  69. return schema
  70. def loadFromString(self, data):
  71. """Return an XMLSchema instance loaded from an XML string.
  72. data -- XML string
  73. """
  74. return self.loadFromStream(StringIO(data))
  75. def loadFromURL(self, url):
  76. """Return an XMLSchema instance loaded from the given url.
  77. url -- URL to dereference
  78. """
  79. if not url.endswith('xsd'):
  80. raise SchemaError, 'unknown file type %s' %url
  81. reader = self.__readerClass()
  82. reader.loadFromURL(url)
  83. schema = XMLSchema()
  84. schema.load(reader)
  85. self.__setIncludes(schema)
  86. self.__setImports(schema)
  87. def loadFromFile(self, filename):
  88. """Return an XMLSchema instance loaded from the given file.
  89. filename -- name of file to open
  90. """
  91. file = open(filename, 'rb')
  92. try: schema = self.loadFromStream(file)
  93. finally: file.close()
  94. return schema
  95. class SchemaError(Exception):
  96. pass
  97. ###########################
  98. # DOM Utility Adapters
  99. ##########################
  100. class DOMAdapterInterface:
  101. def hasattr(self, attr):
  102. """return true if node has attribute
  103. attr - attribute to check for
  104. """
  105. raise NotImplementedError, 'adapter method not implemented'
  106. def getContentList(self, *contents):
  107. """returns an ordered list of child nodes
  108. *contents -- list of node names to return
  109. """
  110. raise NotImplementedError, 'adapter method not implemented'
  111. def setAttributeDictionary(self, attributes):
  112. """set attribute dictionary
  113. """
  114. raise NotImplementedError, 'adapter method not implemented'
  115. def getAttributeDictionary(self):
  116. """returns a dict of node's attributes
  117. """
  118. raise NotImplementedError, 'adapter method not implemented'
  119. def getTagName(self):
  120. """returns tagName of node
  121. """
  122. raise NotImplementedError, 'adapter method not implemented'
  123. def loadDocument(self, file):
  124. """load a Document from a file object
  125. file --
  126. """
  127. raise NotImplementedError, 'adapter method not implemented'
  128. def loadFromURL(self, url):
  129. """load a Document from an url
  130. url -- URL to dereference
  131. """
  132. raise NotImplementedError, 'adapter method not implemented'
  133. class DOMAdapter(DOMAdapterInterface):
  134. """Adapter for ZSI.Utility.DOM
  135. """
  136. def __init__(self, node=None):
  137. """Reset all instance variables.
  138. element -- DOM document, node, or None
  139. """
  140. if hasattr(node, 'documentElement'):
  141. self.__node = node.documentElement
  142. else:
  143. self.__node = node
  144. self.__attributes = None
  145. def hasattr(self, attr):
  146. """XXX assuming all xsd attributes not prefixed,
  147. all others are. Should ask xmlInterface so
  148. it can take care namespace mapping for
  149. prefixed attributes
  150. """
  151. if not self.__attributes:
  152. self.setAttributeDictionary()
  153. return self.__attributes.has_key(attr)
  154. def getContentList(self, *contents):
  155. nodes = []
  156. ELEMENT_NODE = self.__node.ELEMENT_NODE
  157. for child in DOM.getElements(self.__node, None):
  158. if child.nodeType == ELEMENT_NODE and\
  159. SplitQName(child.tagName)[1] in contents:
  160. nodes.append(child)
  161. return map(self.__class__, nodes)
  162. def setAttributeDictionary(self):
  163. self.__attributes = {}
  164. for v in self.__node._attrs.values():
  165. self.__attributes[v.nodeName] = v.nodeValue
  166. def getAttributeDictionary(self):
  167. if not self.__attributes:
  168. self.setAttributeDictionary()
  169. return self.__attributes
  170. def getTagName(self):
  171. return self.__node.tagName
  172. def loadDocument(self, file):
  173. self.__node = DOM.loadDocument(file)
  174. if hasattr(node, 'documentElement'):
  175. self.__node = node.documentElement
  176. def loadFromURL(self, url):
  177. self.__node = DOM.loadFromURL(url)
  178. if hasattr(node, 'documentElement'):
  179. self.__node = node.documentElement
  180. class XMLBase:
  181. """ These class variables are for string indentation.
  182. """
  183. __indent = 0
  184. __rlock = RLock()
  185. def __str__(self):
  186. XMLBase.__rlock.acquire()
  187. XMLBase.__indent += 1
  188. tmp = "<" + str(self.__class__) + '>\n'
  189. for k,v in self.__dict__.items():
  190. tmp += "%s* %s = %s\n" %(XMLBase.__indent*' ', k, v)
  191. XMLBase.__indent -= 1
  192. XMLBase.__rlock.release()
  193. return tmp
  194. ##########################################################
  195. # Schema Components
  196. #########################################################
  197. class XMLSchemaComponent(XMLBase):
  198. """
  199. class variables:
  200. required -- list of required attributes
  201. attributes -- dict of default attribute values, including None.
  202. Value can be a function for runtime dependencies.
  203. contents -- dict of namespace keyed content lists.
  204. 'xsd' content of xsd namespace.
  205. """
  206. required = []
  207. attributes = {}
  208. contents = {}
  209. xmlns_key = ''
  210. def __init__(self, parent=None):
  211. """parent -- parent instance
  212. instance variables:
  213. attributes -- dictionary of node's attributes
  214. """
  215. self.attributes = None
  216. self._parent = parent
  217. if self._parent:
  218. self._parent = weakref.ref(parent)
  219. if not self.__class__ == XMLSchemaComponent\
  220. and not (type(self.__class__.required) == type(XMLSchemaComponent.required)\
  221. and type(self.__class__.attributes) == type(XMLSchemaComponent.attributes)\
  222. and type(self.__class__.contents) == type(XMLSchemaComponent.contents)):
  223. raise RuntimeError, 'Bad type for a class variable in %s' %self.__class__
  224. def getTargetNamespace(self):
  225. """return targetNamespace
  226. """
  227. parent = self
  228. tns = self.attributes.get('targetNamespace')
  229. while not tns:
  230. parent = parent._parent()
  231. tns = parent.attributes.get('targetNamespace')
  232. return tns
  233. def getTypeDefinition(self, attribute):
  234. """attribute -- attribute with a QName value (eg. type).
  235. collection -- check types collection in parent Schema instance
  236. """
  237. return self.getQNameAttribute('types', attribute)
  238. def getElementDeclration(self, attribute):
  239. """attribute -- attribute with a QName value (eg. element).
  240. collection -- check elements collection in parent Schema instance.
  241. """
  242. return self.getQNameAttribute('elements', attribute)
  243. def getQNameAttribute(self, collection, attribute):
  244. """attribute -- an information item attribute, with a QName value.
  245. collection -- collection in parent Schema instance to search.
  246. """
  247. type_def = None
  248. tdc = self.attributes.get(attribute)
  249. if tdc:
  250. parent = self
  251. while not isinstance(parent, Schema):
  252. parent = parent._parent()
  253. if parent.targetNamespace == tdc.getTargetNamespace():
  254. type_def = getattr(parent, collection)[tdc.getName()]
  255. elif parent.imports.has_key(tdc.getTargetNamespace()):
  256. schema = parent.imports[tdc.getTargetNamespace()].getSchema()
  257. type_def = getattr(schema, collection)[tdc.getName()]
  258. else:
  259. raise SchemaError, 'missing import %s' %tdc
  260. return type_def
  261. def getXMLNS(self, prefix=None):
  262. """retrieve contents
  263. empty string returns 'xmlns'
  264. """
  265. parent = self
  266. ns = self.attributes['xmlns'].get(prefix)
  267. while not ns:
  268. parent = parent._parent()
  269. ns = parent.attributes['xmlns'].get(prefix or self.__class__.xmlns_key)
  270. return ns
  271. def getAttribute(self, attribute):
  272. """return requested attribute or None
  273. """
  274. return self.attributes.get(attribute)
  275. def setAttributes(self, node):
  276. """Sets up attribute dictionary, checks for required attributes and
  277. sets default attribute values. attr is for default attribute values
  278. determined at runtime.
  279. """
  280. self.attributes = {'xmlns':{}}
  281. for k,v in node.getAttributeDictionary().items():
  282. prefix,value = SplitQName(k)
  283. if value == 'xmlns':
  284. self.attributes[value][prefix or self.__class__.xmlns_key] = v
  285. elif prefix:
  286. ns = node.getNamespace(prefix)
  287. if ns == XMLNS or prefix == 'xml':
  288. self.attributes['xml'][k] = v
  289. elif ns in XSDNS:
  290. self.attributes[value] = v
  291. else:
  292. raise SchemaError, 'attribute %s, namespace unknown' %k
  293. else:
  294. self.attributes[k] = v
  295. self.__checkAttributes()
  296. self.__setAttributeDefaults()
  297. #set QNames
  298. for k in ['type', 'element', 'base', 'ref', 'substitutionGroup', 'itemType']:
  299. if self.attributes.has_key(k):
  300. prefix, value = SplitQName(self.attributes.get(k))
  301. self.attributes[k] = \
  302. TypeDescriptionComponent((self.getXMLNS(prefix), value))
  303. #Union, memberTypes is a whitespace separated list of QNames
  304. if self.attributes.has_key('memberTypes'):
  305. qnames = self.attributes['memberTypes']
  306. def getContents(self, node):
  307. """retrieve xsd contents
  308. """
  309. return node.getContentList(*self.__class__.contents['xsd'])
  310. def __setAttributeDefaults(self):
  311. """Looks for default values for unset attributes. If
  312. class variable representing attribute is None, then
  313. it must be defined as a instance variable.
  314. """
  315. for k,v in self.attributes.items():
  316. if (not v) and (k != 'xmlns'):
  317. default_attr = getattr(self.__class__.attributes, k)
  318. if isinstance(default_attr, types.FunctionType):
  319. default_attr = default_attr()
  320. self.attributes[k] = default_attr
  321. def __checkAttributes(self):
  322. """Checks that required attributes have been defined,
  323. attributes w/default cannot be required. Checks
  324. all defined attributes are legal.
  325. """
  326. for a in self.__class__.required:
  327. if not self.attributes.has_key(a):
  328. raise SchemaError,\
  329. 'class instance %s, missing required attribute %s'\
  330. %(self.__class__, a)
  331. for a in self.attributes.keys():
  332. if a not in self.__class__.attributes.keys() + ['xmlns']:
  333. raise SchemaError, '%s, unknown attribute' %a
  334. class WSDLToolsAdapter(XMLSchemaComponent):
  335. """WSDL Adapter to grab the attributes from the wsdl document node.
  336. """
  337. attributes = {'name':None, 'targetNamespace':None}
  338. def __init__(self, wsdl):
  339. XMLSchemaComponent.__init__(self, None)
  340. self.setAttributes(DOMAdapter(wsdl.document))
  341. """Marker Interface: can determine something about an instances properties by using
  342. the provided convenience functions.
  343. """
  344. class DefinitionMarker:
  345. """marker for definitions
  346. """
  347. pass
  348. class DeclarationMarker:
  349. """marker for declarations
  350. """
  351. pass
  352. class AttributeMarker:
  353. """marker for attributes
  354. """
  355. pass
  356. class AttributeGroupMarker:
  357. """marker for attribute groups
  358. """
  359. pass
  360. class WildCardMarker:
  361. """marker for wildcards
  362. """
  363. pass
  364. class ElementMarker:
  365. """marker for wildcards
  366. """
  367. pass
  368. class ReferenceMarker:
  369. """marker for references
  370. """
  371. pass
  372. class ModelGroupMarker:
  373. """marker for model groups
  374. """
  375. pass
  376. class ExtensionMarker:
  377. """marker for extensions
  378. """
  379. pass
  380. class RestrictionMarker:
  381. """marker for restrictions
  382. """
  383. facets = ['enumeration', 'length', 'maxExclusive', 'maxInclusive',\
  384. 'maxLength', 'minExclusive', 'minInclusive', 'minLength',\
  385. 'pattern', 'fractionDigits', 'totalDigits', 'whiteSpace']
  386. class SimpleMarker:
  387. """marker for simple type information
  388. """
  389. pass
  390. class ComplexMarker:
  391. """marker for complex type information
  392. """
  393. pass
  394. class MarkerInterface:
  395. def isDefinition(self, what):
  396. return isinstance(what, DefinitionMarker)
  397. def isDeclaration(self, what):
  398. return isinstance(what, DeclarationMarker)
  399. def isAttribute(self, what):
  400. return isinstance(what, AttributeMarker)
  401. def isAttributeGroup(self, what):
  402. return isinstance(what, AttributeGroupMarker)
  403. def isReference(self, what):
  404. return isinstance(what, ReferenceMarker)
  405. def isWildCard(self, what):
  406. return isinstance(what, WildCardMarker)
  407. def isModelGroup(self, what):
  408. return isinstance(what, ModelGroupMarker)
  409. def isExtension(self, what):
  410. return isinstance(what, ModelGroupMarker)
  411. def isRestriction(self, what):
  412. return isinstance(what, ModelGroupMarker)
  413. def isSimple(self, what):
  414. return isinstance(what, SimpleMarker)
  415. def isComplex(self, what):
  416. return isinstance(what, ComplexMarker)
  417. class Notation(XMLSchemaComponent):
  418. """<notation>
  419. parent:
  420. schema
  421. attributes:
  422. id -- ID
  423. name -- NCName, Required
  424. public -- token, Required
  425. system -- anyURI
  426. contents:
  427. annotation?
  428. """
  429. required = ['name', 'public']
  430. attributes = {'id':None, 'name':None, 'public':None, 'system':None}
  431. contents = {'xsd':('annotation')}
  432. def __init__(self):
  433. XMLSchemaComponent.__init__(self)
  434. self.annotation = None
  435. def fromDom(self, node):
  436. self.setAttributes(node)
  437. contents = self.getContents(node)
  438. for i in contents:
  439. component = SplitQName(i.getTagName())[1]
  440. if component == 'annotation' and not self.annotation:
  441. self.annotation = Annotation()
  442. self.annotation.fromDom(i)
  443. else:
  444. raise SchemaError, 'Unknown component (%s)' %(i.getTagName())
  445. class Annotation(XMLSchemaComponent):
  446. """<annotation>
  447. parent:
  448. all,any,anyAttribute,attribute,attributeGroup,choice,complexContent,
  449. complexType,element,extension,field,group,import,include,key,keyref,
  450. list,notation,redefine,restriction,schema,selector,simpleContent,
  451. simpleType,union,unique
  452. attributes:
  453. id -- ID
  454. contents:
  455. (documentation | appinfo)*
  456. """
  457. attributes = {'id':None}
  458. contents = {'xsd':('documentation', 'appinfo')}
  459. def __init__(self):
  460. XMLSchemaComponent.__init__(self)
  461. self.content = None
  462. def fromDom(self, node):
  463. self.setAttributes(node)
  464. contents = self.getContents(node)
  465. content = []
  466. for i in contents:
  467. component = SplitQName(i.getTagName())[1]
  468. if component == 'documentation':
  469. #print_debug('class %s, documentation skipped' %self.__class__, 5)
  470. continue
  471. elif component == 'appinfo':
  472. #print_debug('class %s, appinfo skipped' %self.__class__, 5)
  473. continue
  474. else:
  475. raise SchemaError, 'Unknown component (%s)' %(i.getTagName())
  476. self.content = tuple(content)
  477. class Documentation(XMLSchemaComponent):
  478. """<documentation>
  479. parent:
  480. annotation
  481. attributes:
  482. source, anyURI
  483. xml:lang, language
  484. contents:
  485. mixed, any
  486. """
  487. attributes = {'source':None, 'xml:lang':None}
  488. contents = {'xsd':('mixed', 'any')}
  489. def __init__(self):
  490. XMLSchemaComponent.__init__(self)
  491. self.content = None
  492. def fromDom(self, node):
  493. self.setAttributes(node)
  494. contents = self.getContents(node)
  495. content = []
  496. for i in contents:
  497. component = SplitQName(i.getTagName())[1]
  498. if component == 'mixed':
  499. #print_debug('class %s, mixed skipped' %self.__class__, 5)
  500. continue
  501. elif component == 'any':
  502. #print_debug('class %s, any skipped' %self.__class__, 5)
  503. continue
  504. else:
  505. raise SchemaError, 'Unknown component (%s)' %(i.getTagName())
  506. self.content = tuple(content)
  507. class Appinfo(XMLSchemaComponent):
  508. """<appinfo>
  509. parent:
  510. annotation
  511. attributes:
  512. source, anyURI
  513. contents:
  514. mixed, any
  515. """
  516. attributes = {'source':None, 'anyURI':None}
  517. contents = {'xsd':('mixed', 'any')}
  518. def __init__(self):
  519. XMLSchemaComponent.__init__(self)
  520. self.content = None
  521. def fromDom(self, node):
  522. self.setAttributes(node)
  523. contents = self.getContents(node)
  524. content = []
  525. for i in contents:
  526. component = SplitQName(i.getTagName())[1]
  527. if component == 'mixed':
  528. #print_debug('class %s, mixed skipped' %self.__class__, 5)
  529. continue
  530. elif component == 'any':
  531. #print_debug('class %s, any skipped' %self.__class__, 5)
  532. continue
  533. else:
  534. raise SchemaError, 'Unknown component (%s)' %(i.getTagName())
  535. self.content = tuple(content)
  536. class XMLSchemaFake:
  537. # This is temporary, for the benefit of WSDL until the real thing works.
  538. def __init__(self, element):
  539. self.targetNamespace = DOM.getAttr(element, 'targetNamespace')
  540. self.element = element
  541. class XMLSchema(XMLSchemaComponent):
  542. """A schema is a collection of schema components derived from one
  543. or more schema documents, that is, one or more <schema> element
  544. information items. It represents the abstract notion of a schema
  545. rather than a single schema document (or other representation).
  546. <schema>
  547. parent:
  548. ROOT
  549. attributes:
  550. id -- ID
  551. version -- token
  552. xml:lang -- language
  553. targetNamespace -- anyURI
  554. attributeFormDefault -- 'qualified' | 'unqualified', 'unqualified'
  555. elementFormDefault -- 'qualified' | 'unqualified', 'unqualified'
  556. blockDefault -- '#all' | list of
  557. ('substitution | 'extension' | 'restriction')
  558. finalDefault -- '#all' | list of
  559. ('extension' | 'restriction' | 'list' | 'union')
  560. contents:
  561. ((include | import | redefine | annotation)*,
  562. (attribute, attributeGroup, complexType, element, group,
  563. notation, simpleType)*, annotation*)*
  564. attributes -- schema attributes
  565. imports -- import statements
  566. includes -- include statements
  567. redefines --
  568. types -- global simpleType, complexType definitions
  569. elements -- global element declarations
  570. attr_decl -- global attribute declarations
  571. attr_groups -- attribute Groups
  572. model_groups -- model Groups
  573. notations -- global notations
  574. """
  575. attributes = {'id':None,
  576. 'version':None,
  577. 'xml:lang':None,
  578. 'targetNamespace':None,
  579. 'attributeFormDefault':'unqualified',
  580. 'elementFormDefault':'unqualified',
  581. 'blockDefault':None,
  582. 'finalDefault':None}
  583. contents = {'xsd':('include', 'import', 'redefine', 'annotation', 'attribute',\
  584. 'attributeGroup', 'complexType', 'element', 'group',\
  585. 'notation', 'simpleType', 'annotation')}
  586. empty_namespace = ''
  587. def __init__(self, parent=None):
  588. """parent --
  589. instance variables:
  590. targetNamespace -- schema's declared targetNamespace, or empty string.
  591. _imported_schemas -- namespace keyed dict of schema dependencies, if
  592. a schema is provided instance will not resolve import statement.
  593. _included_schemas -- schemaLocation keyed dict of component schemas,
  594. if schema is provided instance will not resolve include statement.
  595. _base_url -- needed for relative URLs support, only works with URLs
  596. relative to initial document.
  597. includes -- collection of include statements
  598. imports -- collection of import statements
  599. elements -- collection of global element declarations
  600. types -- collection of global type definitions
  601. attr_decl -- collection of global attribute declarations
  602. attr_groups -- collection of global attribute group definitions
  603. model_groups -- collection of model group definitions
  604. notations -- collection of notations
  605. """
  606. self.targetNamespace = None
  607. XMLSchemaComponent.__init__(self, parent)
  608. self.includes = Collection(self)
  609. self.imports = Collection(self)
  610. self.elements = Collection(self)
  611. self.types = Collection(self)
  612. self.attr_decl = Collection(self)
  613. self.attr_groups = Collection(self)
  614. self.model_groups = Collection(self)
  615. self.notations = Collection(self)
  616. self._imported_schemas = {}
  617. self._included_schemas = {}
  618. self._base_url = None
  619. def addImportSchema(self, schema):
  620. """for resolving import statements in Schema instance
  621. schema -- schema instance
  622. _imported_schemas
  623. """
  624. if not isinstance(schema, Schema):
  625. raise TypeError, 'expecting a Schema instance'
  626. if schema.targetNamespace != self.targetNamespace:
  627. self._imported_schemas[schema.targetNamespace]
  628. else:
  629. raise SchemaError, 'import schema bad targetNamespace'
  630. def addIncludeSchema(self, schemaLocation, schema):
  631. """for resolving include statements in Schema instance
  632. schemaLocation -- schema location
  633. schema -- schema instance
  634. _included_schemas
  635. """
  636. if not isinstance(schema, Schema):
  637. raise TypeError, 'expecting a Schema instance'
  638. if not schema.targetNamespace or\
  639. schema.targetNamespace == self.targetNamespace:
  640. self._included_schemas[schemaLocation] = schema
  641. else:
  642. raise SchemaError, 'include schema bad targetNamespace'
  643. def setImportSchemas(self, schema_dict):
  644. """set the import schema dictionary, which is used to
  645. reference depedent schemas.
  646. """
  647. self._imported_schemas = schema_dict
  648. def getImportSchemas(self):
  649. """get the import schema dictionary, which is used to
  650. reference depedent schemas.
  651. """
  652. return self._imported_schemas
  653. def getSchemaNamespacesToImport(self):
  654. """returns tuple of namespaces the schema instance has declared
  655. itself to be depedent upon.
  656. """
  657. return tuple(self.includes.keys())
  658. def setIncludeSchemas(self, schema_dict):
  659. """set the include schema dictionary, which is keyed with
  660. schemaLocation (uri).
  661. This is a means of providing
  662. schemas to the current schema for content inclusion.
  663. """
  664. self._included_schemas = schema_dict
  665. def getIncludeSchemas(self):
  666. """get the include schema dictionary, which is keyed with
  667. schemaLocation (uri).
  668. """
  669. return self._included_schemas
  670. def getBaseUrl(self):
  671. """get base url, used for normalizing all relative uri's
  672. """
  673. return self._base_url
  674. def setBaseUrl(self, url):
  675. """set base url, used for normalizing all relative uri's
  676. """
  677. self._base_url = url
  678. def load(self, node):
  679. self.setAttributes(node)
  680. self.targetNamespace = self.getTargetNamespace()
  681. contents = self.getContents(node)
  682. indx = 0
  683. num = len(contents)
  684. while indx < num:
  685. while indx < num:
  686. node = contents[indx]
  687. component = SplitQName(node.getTagName())[1]
  688. if component == 'include':
  689. tp = self.__class__.Include(self)
  690. tp.fromDom(node)
  691. self.includes[tp.attributes['schemaLocation']] = tp
  692. schema = tp.getSchema()
  693. if schema.targetNamespace and \
  694. schema.targetNamespace != self.targetNamespace:
  695. raise SchemaError, 'included schema bad targetNamespace'
  696. for collection in ['imports','elements','types',\
  697. 'attr_decl','attr_groups','model_groups','notations']:
  698. for k,v in getattr(schema,collection).items():
  699. if not getattr(self,collection).has_key(k):
  700. setattr(self,collection,v)
  701. elif component == 'import':
  702. tp = self.__class__.Import(self)
  703. tp.fromDom(node)
  704. if tp.attributes['namespace']:
  705. if tp.attributes['namespace'] == self.targetNamespace:
  706. raise SchemaError,\
  707. 'import and schema have same targetNamespace'
  708. self.imports[tp.attributes['namespace']] = tp
  709. else:
  710. self.imports[self.__class__.empty_namespace] = tp
  711. elif component == 'redefine':
  712. #print_debug('class %s, redefine skipped' %self.__class__, 5)
  713. pass
  714. elif component == 'annotation':
  715. #print_debug('class %s, annotation skipped' %self.__class__, 5)
  716. pass
  717. else:
  718. break
  719. indx += 1
  720. while indx < num:
  721. node = contents[indx]
  722. component = SplitQName(node.getTagName())[1]
  723. if component == 'complexType':
  724. tp = ComplexType(self)
  725. tp.fromDom(node)
  726. self.types[tp.getAttribute('name')] = tp
  727. elif component == 'element':
  728. tp = ElementDeclaration(self)
  729. tp.fromDom(node)
  730. self.elements[tp.getAttribute('name')] = tp
  731. elif component == 'simpleType':
  732. tp = SimpleType(self)
  733. tp.fromDom(node)
  734. self.types[tp.getAttribute('name')] = tp
  735. elif component == 'group':
  736. tp = ModelGroupDefinition(self)
  737. tp.fromDom(node)
  738. self.modelGroups[tp.getAttribute('name')] = tp
  739. elif component == 'notation':
  740. tp = Notation(self)
  741. tp.fromDom(node)
  742. self.notations[tp.getAttribute('name')] = tp
  743. else:
  744. break
  745. indx += 1
  746. while indx < num:
  747. node = contents[indx]
  748. component = SplitQName(node.getTagName())[1]
  749. if component == 'annotation':
  750. #print_debug('class %s, annotation 2 skipped' %self.__class__, 5)
  751. pass
  752. else:
  753. break
  754. indx += 1
  755. class Import(XMLSchemaComponent):
  756. """<import>
  757. parent:
  758. schema
  759. attributes:
  760. id -- ID
  761. namespace -- anyURI
  762. schemaLocation -- anyURI
  763. contents:
  764. annotation?
  765. """
  766. attributes = {'id':None,
  767. 'namespace':None,
  768. 'schemaLocation':None}
  769. contents = {'xsd':['annotation']}
  770. def __init__(self, parent):
  771. XMLSchemaComponent.__init__(self, parent)
  772. self.annotation = None
  773. def fromDom(self, node):
  774. self.setAttributes(node)
  775. contents = self.getContents(node)
  776. if self.attributes['namespace'] == self._parent().attributes['targetNamespace']:
  777. raise SchemaError, 'namespace (%s) of schema and import match'
  778. for i in contents:
  779. component = SplitQName(i.getTagName())[1]
  780. if component == 'annotation' and not self.annotation:
  781. self.annotation = Annotation()
  782. self.annotation.fromDom(i)
  783. else:
  784. raise SchemaError, 'Unknown component (%s)' %(i.getTagName())
  785. def getSchema(self):
  786. """if schema is not defined, first look for a Schema class instance
  787. in parent Schema. Else if not defined resolve schemaLocation
  788. and create a new Schema class instance.
  789. """
  790. if not self._schema:
  791. schema = self._parent()._parent()
  792. self._schema = schema.getImportSchemas()[self.attributes['namespace']]
  793. if not self._schema:
  794. url = urllib.basejoin(schema.getBaseUrl(),\
  795. self.attributes['schemaLocation'])
  796. reader = SchemaReader()
  797. reader._imports = schema.getImportSchemas()
  798. reader._includes = schema.getIncludeSchemas()
  799. self._schema = reader.readFromUrl(url)
  800. self._schema.setBaseUrl(url)
  801. return self._schema
  802. class Include(XMLSchemaComponent):
  803. """<include schemaLocation>
  804. parent:
  805. schema
  806. attributes:
  807. id -- ID
  808. schemaLocation -- anyURI, required
  809. contents:
  810. annotation?
  811. """
  812. required = ['schemaLocation']
  813. attributes = {'id':None,
  814. 'schemaLocation':None}
  815. contents = {'xsd':['annotation']}
  816. def __init__(self, parent):
  817. XMLSchemaComponent.__init__(self, parent)
  818. self.annotation = None
  819. self._schema = None
  820. def fromDom(self, node):
  821. self.setAttributes(node)
  822. contents = self.getContents(node)
  823. for i in contents:
  824. component = SplitQName(i.getTagName())[1]
  825. if component == 'annotation' and not self.annotation:
  826. self.annotation = Annotation()
  827. self.annotation.fromDom(i)
  828. else:
  829. raise SchemaError, 'Unknown component (%s)' %(i.getTagName())
  830. def getSchema(self):
  831. """if schema is not defined, first look for a Schema class instance
  832. in parent Schema. Else if not defined resolve schemaLocation
  833. and create a new Schema class instance.
  834. """
  835. if not self._schema:
  836. schema = self._parent()._parent()
  837. self._schema = schema.getIncludeSchemas(\
  838. self.attributes['schemaLocation'])
  839. if not self._schema:
  840. url = BaseUriResolver().normalize(\
  841. self.attributes['schemaLocation'], schema.getBaseUrl())
  842. reader = SchemaReader()
  843. reader._imports = schema.getImportSchemas()
  844. reader._includes = schema.getIncludeSchemas()
  845. self._schema = reader.readFromUrl(url)
  846. self._schema.setBaseUrl(url)
  847. return self._schema
  848. class AttributeDeclaration(XMLSchemaComponent,\
  849. MarkerInterface,\
  850. AttributeMarker,\
  851. DeclarationMarker):
  852. """<attribute name>
  853. parent:
  854. schema
  855. attributes:
  856. id -- ID
  857. name -- NCName, required
  858. type -- QName
  859. default -- string
  860. fixed -- string
  861. contents:
  862. annotation?, simpleType?
  863. """
  864. required = ['name']
  865. attributes = {'id':None,
  866. 'name':None,
  867. 'type':None,
  868. 'default':None,
  869. 'fixed':None}
  870. contents = {'xsd':['annotation','simpleType']}
  871. def __init__(self, parent):
  872. XMLSchemaComponent.__init__(self, parent)
  873. self.annotation = None
  874. self.content = None
  875. def fromDom(self, node):
  876. """ No list or union support
  877. """
  878. self.setAttributes(node)
  879. contents = self.getContents(node)
  880. for i in contents:
  881. component = SplitQName(i.getTagName())[1]
  882. if component == 'annotation' and not self.annotation:
  883. self.annotation = Annotation(self)
  884. self.annotation.fromDom(i)
  885. elif component == 'simpleType':
  886. self.content = SimpleType(self)
  887. self.content.fromDom(i)
  888. else:
  889. raise SchemaError, 'Unknown component (%s)' %(i.getTagName())
  890. class LocalAttributeDeclaration(AttributeDeclaration,\
  891. MarkerInterface,\
  892. AttributeMarker,\
  893. DeclarationMarker):
  894. """<attribute name>
  895. parent:
  896. complexType, restriction, extension, attributeGroup
  897. attributes:
  898. id -- ID
  899. name -- NCName, required
  900. type -- QName
  901. form -- ('qualified' | 'unqualified'), schema.attributeFormDefault
  902. use -- ('optional' | 'prohibited' | 'required'), optional
  903. default -- string
  904. fixed -- string
  905. contents:
  906. annotation?, simpleType?
  907. """
  908. required = ['name']
  909. attributes = {'id':None,
  910. 'name':None,
  911. 'type':None,
  912. 'form':lambda: self._parent.parent().getAttributeFormDefault(),
  913. 'use':'optional',
  914. 'default':None,
  915. 'fixed':None}
  916. contents = {'xsd':['annotation','simpleType']}
  917. def __init__(self, parent):
  918. AttributeDeclaration.__init__(self, parent)
  919. self.annotation = None
  920. self.content = None
  921. def fromDom(self, node):
  922. self.setAttributes(node)
  923. contents = self.getContents(node)
  924. for i in contents:
  925. component = SplitQName(i.getTagName())[1]
  926. if component == 'annotation' and not self.annotation:
  927. self.annotation = Annotation(self)
  928. self.annotation.fromDom(i)
  929. elif component == 'simpleType':
  930. self.content = SimpleType(self)
  931. self.content.fromDom(i)
  932. else:
  933. raise SchemaError, 'Unknown component (%s)' %(i.getTagName())
  934. class AttributeWildCard(XMLSchemaComponent,\
  935. MarkerInterface,\
  936. AttributeMarker,\
  937. DeclarationMarker,\
  938. WildCardMarker):
  939. """<anyAttribute>
  940. parents:
  941. complexType, restriction, extension, attributeGroup
  942. attributes:
  943. id -- ID
  944. namespace -- '##any' | '##other' |
  945. (anyURI* | '##targetNamespace' | '##local'), ##any
  946. processContents -- 'lax' | 'skip' | 'strict', strict
  947. contents:
  948. annotation?
  949. """
  950. attributes = {'id':None,
  951. 'namespace':'##any',
  952. 'processContents':'strict'}
  953. contents = {'xsd':['annotation']}
  954. def __init__(self, parent):
  955. XMLSchemaComponent.__init__(self, parent)
  956. self.annotation = None
  957. def fromDom(self, node):
  958. self.setAttributes(node)
  959. contents = self.getContents(node)
  960. for i in contents:
  961. component = SplitQName(i.getTagName())[1]
  962. if component == 'annotation' and not self.annotation:
  963. self.annotation = Annotation()
  964. self.annotation.fromDom(i)
  965. else:
  966. raise SchemaError, 'Unknown component (%s)' %(i.getTagName())
  967. class AttributeReference(XMLSchemaComponent,\
  968. MarkerInterface,\
  969. AttributeMarker,\
  970. ReferenceMarker):
  971. """<attribute ref>
  972. parents:
  973. complexType, restriction, extension, attributeGroup
  974. attributes:
  975. id -- ID
  976. ref -- QName, required
  977. use -- ('optional' | 'prohibited' | 'required'), optional
  978. default -- string
  979. fixed -- string
  980. contents:
  981. annotation?
  982. """
  983. required = ['ref']
  984. attributes = {'id':None,
  985. 'ref':None,
  986. 'use':'optional',
  987. 'default':None,
  988. 'fixed':None}
  989. contents = {'xsd':['annotation']}
  990. def __init__(self, schemaEval):
  991. XMLSchemaComponent.__init__(self)
  992. self.annotation = None
  993. def fromDom(self, node):
  994. self.setAttributes(node)
  995. contents = self.getContents(node)
  996. for i in contents:
  997. component = SplitQName(i.getTagName())[1]
  998. if component == 'annotation' and not self.annotation:
  999. self.annotation = Annotation()
  1000. self.annotation.fromDom(i)
  1001. else:
  1002. raise SchemaError, 'Unknown component (%s)' %(i.getTagName())
  1003. class AttributeGroupDefinition(XMLSchemaComponent,\
  1004. MarkerInterface,\
  1005. AttributeGroupMarker,\
  1006. DefinitionMarker):
  1007. """<attributeGroup name>
  1008. parents:
  1009. schema, redefine
  1010. attributes:
  1011. id -- ID
  1012. name -- NCName, required
  1013. contents:
  1014. annotation?
  1015. """
  1016. required = ['name']
  1017. attributes = {'id':None,
  1018. 'name':None}
  1019. contents = {'xsd':['annotation']}
  1020. def __init__(self, schemaEval):
  1021. XMLSchemaComponent.__init__(self)
  1022. self.annotation = None
  1023. def fromDom(self, node):
  1024. self.setAttributes(node)
  1025. contents = self.getContents(node)
  1026. for i in contents:
  1027. component = SplitQName(i.getTagName())[1]
  1028. if component == 'annotation' and not self.annotation:
  1029. self.annotation = Annotation()
  1030. self.annotation.fromDom(i)
  1031. else:
  1032. raise SchemaError, 'Unknown component (%s)' %(i.getTagName())
  1033. class AttributeGroupReference(XMLSchemaComponent,\
  1034. MarkerInterface,\
  1035. AttributeGroupMarker,\
  1036. ReferenceMarker):
  1037. """<attributeGroup ref>
  1038. parents:
  1039. complexType, restriction, extension, attributeGroup
  1040. attributes:
  1041. id -- ID
  1042. ref -- QName, required
  1043. contents:
  1044. annotation?
  1045. """
  1046. required = ['ref']
  1047. attributes = {'id':None,
  1048. 'ref':None}
  1049. contents = {'xsd':['annotation']}
  1050. def __init__(self, parent):
  1051. XMLSchemaComponent.__init__(self, parent)
  1052. self.annotation = None
  1053. def fromDom(self, node):
  1054. self.setAttributes(node)
  1055. contents = self.getContents(node)
  1056. for i in contents:
  1057. component = SplitQName(i.getTagName())[1]
  1058. if component == 'annotation' and not self.annotation:
  1059. self.annotation = Annotation()
  1060. self.annotation.fromDom(i)
  1061. else:
  1062. raise SchemaError, 'Unknown component (%s)' %(i.getTagName())
  1063. ######################################################
  1064. # Elements
  1065. #####################################################
  1066. class IdentityConstrants(XMLSchemaComponent):
  1067. """Allow one to uniquely identify nodes in a document and ensure the
  1068. integrity of references between them.
  1069. attributes -- dictionary of attributes
  1070. selector -- XPath to selected nodes
  1071. fields -- list of XPath to key field
  1072. """
  1073. def __init__(self):
  1074. XMLSchemaComponent.__init__(self)
  1075. self.selector = None
  1076. self.fields = None
  1077. self.annotation = None
  1078. def fromDom(node):
  1079. self.setAttributes(node)
  1080. contents = self.getContents(node)
  1081. fields = []
  1082. for i in contents:
  1083. component = SplitQName(i.getTagName())[1]
  1084. if component in self.__class__.contents['xsd']:
  1085. if component == 'annotation' and not self.annotation:
  1086. self.annotation = Annotation()
  1087. self.annotation.fromDom(i)
  1088. elif component == 'selector':
  1089. self.selector = self.Selector()
  1090. self.selector.fromDom(i)
  1091. continue
  1092. elif component == 'field':
  1093. fields.append(self.Field())
  1094. fields[-1].fromDom(i)
  1095. continue
  1096. else:
  1097. raise SchemaError, 'Unknown component (%s)' %(i.getTagName())
  1098. else:
  1099. raise SchemaError, 'Unknown component (%s)' %(i.getTagName())
  1100. self.fields = tuple(fields)
  1101. class Constraint(XMLSchemaComponent):
  1102. def __init__(self):
  1103. XMLSchemaComponent.__init__(self)
  1104. self.annotation = None
  1105. def fromDom(node):
  1106. self.setAttributes(node)
  1107. contents = self.getContents(node)
  1108. for i in contents:
  1109. component = SplitQName(i.getTagName())[1]
  1110. if component in self.__class__.contents['xsd']:
  1111. if component == 'annotation' and not self.annotation:
  1112. self.annotation = Annotation()
  1113. self.annotation.fromDom(i)
  1114. else:
  1115. raise SchemaError, 'Unknown component (%s)' %(i.getTagName())
  1116. else:
  1117. raise SchemaError, 'Unknown component (%s)' %(i.getTagName())
  1118. class Selector(Constraint):
  1119. """<selector xpath>
  1120. parent:
  1121. unique, key, keyref
  1122. attributes:
  1123. id -- ID
  1124. xpath -- XPath subset, required
  1125. contents:
  1126. annotation?
  1127. """
  1128. required = ['xpath']
  1129. attributes = {'id':None,
  1130. 'xpath':None}
  1131. contents = {'xsd':['annotation']}
  1132. class Field(Constraint):
  1133. """<field xpath>
  1134. parent:
  1135. unique, key, keyref
  1136. attributes:
  1137. id -- ID
  1138. xpath -- XPath subset, required
  1139. contents:
  1140. annotation?
  1141. """
  1142. required = ['xpath']
  1143. attributes = {'id':None,
  1144. 'xpath':None}
  1145. contents = {'xsd':['annotation']}
  1146. class Unique(IdentityConstrants):
  1147. """<unique name> Enforce fields are unique w/i a specified scope.
  1148. parent:
  1149. element
  1150. attributes:
  1151. id -- ID
  1152. name -- NCName, required
  1153. contents:
  1154. annotation?, selector, field+
  1155. """
  1156. required = ['name']
  1157. attributes = {'id':None,
  1158. 'name':None}
  1159. contents = {'xsd':['annotation', 'selector', 'field']}
  1160. class Key(IdentityConstrants):
  1161. """<key name> Enforce fields are unique w/i a specified scope, and all
  1162. field values are present w/i document. Fields cannot
  1163. be nillable.
  1164. parent:
  1165. element
  1166. attributes:
  1167. id -- ID
  1168. name -- NCName, required
  1169. contents:
  1170. annotation?, selector, field+
  1171. """
  1172. required = ['name']
  1173. attributes = {'id':None,
  1174. 'name':None}
  1175. contents = {'xsd':['annotation', 'selector', 'field']}
  1176. class KeyRef(IdentityConstrants):
  1177. """<keyref name refer> Ensure a match between two sets of values in an
  1178. instance.
  1179. parent:
  1180. element
  1181. attributes:
  1182. id -- ID
  1183. name -- NCName, required
  1184. refer -- QName, required
  1185. contents:
  1186. annotation?, selector, field+
  1187. """
  1188. required = ['name', 'refer']
  1189. attributes = {'id':None,
  1190. 'name':None,
  1191. 'refer':None}
  1192. contents = {'xsd':['annotation', 'selector', 'field']}
  1193. class ElementDeclaration(XMLSchemaComponent,\
  1194. MarkerInterface,\
  1195. ElementMarker,\
  1196. DeclarationMarker):
  1197. """<element name>
  1198. parents:
  1199. schema
  1200. attributes:
  1201. id -- ID
  1202. name -- NCName, required
  1203. type -- QName
  1204. default -- string
  1205. fixed -- string
  1206. nillable -- boolean, false
  1207. abstract -- boolean, false
  1208. substitutionGroup -- QName
  1209. block -- ('#all' | ('substition' | 'extension' | 'restriction')*),
  1210. schema.blockDefault
  1211. final -- ('#all' | ('extension' | 'restriction')*),
  1212. schema.finalDefault
  1213. contents:
  1214. annotation?, (simpleType,complexType)?, (key | keyref | unique)*
  1215. """
  1216. required = ['name']
  1217. attributes = {'id':None,
  1218. 'name':None,
  1219. 'type':None,
  1220. 'default':None,
  1221. 'fixed':None,
  1222. 'nillable':0,
  1223. 'abstract':0,
  1224. 'block':lambda: self.parent.parent().getBlockDefault(),
  1225. 'final':lambda: self.parent.parent().getFinalDefault()}
  1226. contents = {'xsd':['annotation', 'simpleType', 'complexType', 'key',\
  1227. 'keyref', 'unique']}
  1228. def __init__(self, parent):
  1229. XMLSchemaComponent.__init__(self, parent)
  1230. self.annotation = None
  1231. self.content = None
  1232. self.constraints = None
  1233. def fromDom(self, node):
  1234. self.setAttributes(node)
  1235. contents = self.getContents(node)
  1236. constraints = []
  1237. for i in contents:
  1238. component = SplitQName(i.getTagName())[1]
  1239. if component in self.__class__.contents['xsd']:
  1240. if component == 'annotation' and not self.annotation:
  1241. self.annotation = Annotation(self)
  1242. self.annotation.fromDom(i)
  1243. elif component == 'simpleType' and not self.content:
  1244. self.content = AnonymousSimpleType(self)
  1245. self.content.fromDom(i)
  1246. elif component == 'complexType' and not self.content:
  1247. self.content = LocalComplexType(self)
  1248. self.content.fromDom(i)
  1249. elif component == 'key':
  1250. constraints.append(Key(self))
  1251. constraints[-1].fromDom(i)
  1252. elif component == 'keyref':
  1253. constraints.append(KeyRef(self))
  1254. constraints[-1].fromDom(i)
  1255. elif component == 'unique':
  1256. constraints.append(Unique(self))
  1257. constraints[-1].fromDom(i)
  1258. else:
  1259. raise SchemaError, 'Unknown component (%s)' %(i.getTagName())
  1260. else:
  1261. raise SchemaError, 'Unknown component (%s)' %(i.getTagName())
  1262. self.constraints = tuple(constraints)
  1263. class LocalElementDeclaration(ElementDeclaration,\
  1264. MarkerInterface,\
  1265. ElementMarker,\
  1266. DeclarationMarker):
  1267. """<element>
  1268. parents:
  1269. all, choice, sequence
  1270. attributes:
  1271. id -- ID
  1272. name -- NCName, required
  1273. form -- ('qualified' | 'unqualified'), schema.elementFormDefault
  1274. type -- QName
  1275. minOccurs -- Whole Number, 1
  1276. maxOccurs -- (Whole Number | 'unbounded'), 1
  1277. default -- string
  1278. fixed -- string
  1279. nillable -- boolean, false
  1280. block -- ('#all' | ('extension' | 'restriction')*), schema.blockDefault
  1281. contents:
  1282. annotation?, (simpleType,complexType)?, (key | keyref | unique)*
  1283. """
  1284. required = ['name']
  1285. attributes = {'id':None,
  1286. 'name':None,
  1287. 'form':lambda: self._parent.parent().getElementFormDefault(),
  1288. 'type':None,
  1289. 'minOccurs':'1',
  1290. 'maxOccurs':'1',
  1291. 'default':None,
  1292. 'fixed':None,
  1293. 'nillable':0,
  1294. 'abstract':0,
  1295. 'block':lambda: self.parent.parent().getBlockDefault()}
  1296. contents = {'xsd':['annotation', 'simpleType', 'complexType', 'key',\
  1297. 'keyref', 'unique']}
  1298. class ElementReference(ElementDeclaration,\
  1299. MarkerInterface,\
  1300. ElementMarker,\
  1301. ReferenceMarker):
  1302. """<element ref>
  1303. parents:
  1304. all, choice, sequence
  1305. attributes:
  1306. id -- ID
  1307. ref -- QName, required
  1308. minOccurs -- Whole Number, 1
  1309. maxOccurs -- (Whole Number | 'unbounded'), 1
  1310. contents:
  1311. annotation?
  1312. """
  1313. required = ['ref']
  1314. attributes = {'id':None,
  1315. 'ref':None,
  1316. 'minOccurs':'1',
  1317. 'maxOccurs':'1'}
  1318. contents = {'xsd':['annotation']}
  1319. class ElementWildCard(LocalElementDeclaration,\
  1320. MarkerInterface,\
  1321. ElementMarker,\
  1322. DeclarationMarker,\
  1323. WildCardMarker):
  1324. """<any>
  1325. parents:
  1326. choice, sequence
  1327. attributes:
  1328. id -- ID
  1329. minOccurs -- Whole Number, 1
  1330. maxOccurs -- (Whole Number | 'unbounded'), 1
  1331. namespace -- '##any' | '##other' |
  1332. (anyURI* | '##targetNamespace' | '##local'), ##any
  1333. processContents -- 'lax' | 'skip' | 'strict', strict
  1334. contents:
  1335. annotation?
  1336. """
  1337. required = []
  1338. attributes = {'id':None,
  1339. 'minOccurs':'1',
  1340. 'maxOccurs':'1',
  1341. 'namespace':'##any',
  1342. 'processContents':'strict'}
  1343. contents = {'xsd':['annotation']}
  1344. ######################################################
  1345. # Model Groups
  1346. #####################################################
  1347. class Sequence(XMLSchemaComponent,\
  1348. MarkerInterface,\
  1349. ModelGroupMarker):
  1350. """<sequence>
  1351. parents:
  1352. complexType, extension, restriction, group, choice, sequence
  1353. attributes:
  1354. id -- ID
  1355. minOccurs -- Whole Number, 1
  1356. maxOccurs -- (Whole Number | 'unbounded'), 1
  1357. contents:
  1358. annotation?, (element | group | choice | sequence | any)*
  1359. """
  1360. attributes = {'id':None,
  1361. 'minOccurs':'1',
  1362. 'maxOccurs':'1'}
  1363. contents = {'xsd':['annotation', 'element', 'group', 'choice', 'sequence',\
  1364. 'any']}
  1365. def __init__(self, parent):
  1366. XMLSchemaComponent.__init__(self, parent)
  1367. self.annotation = None
  1368. self.content = None
  1369. def fromDom(self, node):
  1370. self.setAttributes(node)
  1371. contents = self.getContents(node)
  1372. content = []
  1373. for i in contents:
  1374. component = SplitQName(i.getTagName())[1]
  1375. if component in self.__class__.contents['xsd']:
  1376. if component == 'annotation' and not self.annotation:
  1377. self.annotation = Annotation()
  1378. self.annotation.fromDom(i)
  1379. continue
  1380. elif component == 'element':
  1381. if i.hasattr('ref'):
  1382. content.append(ElementReference(self))
  1383. else:
  1384. content.append(LocalElementDeclaration(self))
  1385. elif component == 'group':
  1386. content.append(ModelGroupReference(self))
  1387. elif component == 'choice':
  1388. content.append(Choice(self))
  1389. elif component == 'sequence':
  1390. content.append(Sequence(self))
  1391. elif component == 'any':
  1392. content.append(ElementWildCard(self))
  1393. else:
  1394. raise SchemaError, 'Unknown component (%s)' %(i.getTagName())
  1395. content[-1].fromDom(i)
  1396. else:
  1397. raise SchemaError, 'Unknown component (%s)' %(i.getTagName())
  1398. self.content = tuple(content)
  1399. class All(XMLSchemaComponent,\
  1400. MarkerInterface,\
  1401. ModelGroupMarker):
  1402. """<all>
  1403. parents:
  1404. complexType, extension, restriction, group
  1405. attributes:
  1406. id -- ID
  1407. minOccurs -- '0' | '1', 1
  1408. maxOccurs -- '1', 1
  1409. contents:
  1410. annotation?, element*
  1411. """
  1412. attributes = {'id':None,
  1413. 'minOccurs':'1',
  1414. 'maxOccurs':'1'}
  1415. contents = {'xsd':['annotation', 'element']}
  1416. def __init__(self, parent):
  1417. XMLSchemaComponent.__init__(self, parent)
  1418. self.annotation = None
  1419. self.content = None
  1420. def fromDom(self, node):
  1421. self.setAttributes(node)
  1422. contents = self.getContents(node)
  1423. content = []
  1424. for i in contents:
  1425. component = SplitQName(i.getTagName())[1]
  1426. if component in self.__class__.contents['xsd']:
  1427. if component == 'annotation' and not self.annotation:
  1428. self.annotation = Annotation()
  1429. self.annotation.fromDom(i)
  1430. continue
  1431. elif component == 'element':
  1432. if i.hasattr('ref'):
  1433. content.append(ElementReference())
  1434. else:
  1435. content.append(LocalElementDeclaration())
  1436. else:
  1437. raise SchemaError, 'Unknown component (%s)' %(i.getTagName())
  1438. content[-1].fromDom(i)
  1439. else:
  1440. raise SchemaError, 'Unknown component (%s)' %(i.getTagName())
  1441. self.content = tuple(content)
  1442. class Choice(XMLSchemaComponent,\
  1443. MarkerInterface,\
  1444. ModelGroupMarker):
  1445. """<choice>
  1446. parents:
  1447. complexType, extension, restriction, group, choice, sequence
  1448. attributes:
  1449. id -- ID
  1450. minOccurs -- Whole Number, 1
  1451. maxOccurs -- (Whole Number | 'unbounded'), 1
  1452. contents:
  1453. annotation?, (element | group | choice | sequence | any)*
  1454. """
  1455. attributes = {'id':None,
  1456. 'minOccurs':'1',
  1457. 'maxOccurs':'1'}
  1458. contents = {'xsd':['annotation', 'element', 'group', 'choice', 'sequence',\
  1459. 'any']}
  1460. def __init__(self, parent):
  1461. XMLSchemaComponent.__init__(self, parent)
  1462. self.annotation = None
  1463. self.content = None
  1464. def fromDom(self, node):
  1465. self.setAttributes(node)
  1466. contents = self.getContents(node)
  1467. content = []
  1468. for i in contents:
  1469. component = SplitQName(i.getTagName())[1]
  1470. if component in self.__class__.contents['xsd']:
  1471. if component == 'annotation' and not self.annotation:
  1472. self.annotation = Annotation()
  1473. self.annotation.fromDom(i)
  1474. continue
  1475. elif component == 'element':
  1476. if i.hasattr('ref'):
  1477. content.append(ElementReference())
  1478. else:
  1479. content.append(LocalElementDeclaration())
  1480. elif component == 'group':
  1481. content.append(ModelGroupReference())
  1482. elif component == 'choice':
  1483. content.append(Choice())
  1484. elif component == 'sequence':
  1485. content.append(Sequence())
  1486. elif component == 'any':
  1487. content.append(ElementWildCard())
  1488. else:
  1489. raise SchemaError, 'Unknown component (%s)' %(i.getTagName())
  1490. content[-1].fromDom(i)
  1491. else:
  1492. raise SchemaError, 'Unknown component (%s)' %(i.getTagName())
  1493. self.content = tuple(content)
  1494. class ModelGroupDefinition(XMLSchemaComponent,\
  1495. MarkerInterface,\
  1496. ModelGroupMarker,\
  1497. DefinitionMarker):
  1498. """<group name>
  1499. parents:
  1500. redefine, schema
  1501. attributes:
  1502. id -- ID
  1503. name -- NCName, required
  1504. contents:
  1505. annotation?, (all | choice | sequence)?
  1506. """
  1507. required = ['name']
  1508. attributes = {'id':None,
  1509. 'name':None}
  1510. contents = {'xsd':['annotation', 'all', 'choice', 'sequence']}
  1511. def __init__(self, parent):
  1512. XMLSchemaComponent.__init__(self, parent)
  1513. self.annotation = None
  1514. self.content = None
  1515. def fromDom(self, node):
  1516. self.setAttributes(node)
  1517. contents = self.getContents(node)
  1518. for i in contents:
  1519. component = SplitQName(i.getTagName())[1]
  1520. if component in self.__class__.contents['xsd']:
  1521. if component == 'annotation' and not self.annotation:
  1522. self.annotation = Annotation()
  1523. self.annotation.fromDom(i)
  1524. continue
  1525. elif component == 'all' and not self.content:
  1526. self.content = All()
  1527. elif component == 'choice' and not self.content:
  1528. self.content = Choice()
  1529. elif component == 'sequence' and not self.content:
  1530. self.content = Sequence()
  1531. else:
  1532. raise SchemaError, 'Unknown component (%s)' %(i.getTagName())
  1533. self.content.fromDom(i)
  1534. else:
  1535. raise SchemaError, 'Unknown component (%s)' %(i.getTagName())
  1536. class ModelGroupReference(XMLSchemaComponent,\
  1537. MarkerInterface,\
  1538. ModelGroupMarker,\
  1539. ReferenceMarker):
  1540. """<group ref>
  1541. parents:
  1542. choice, complexType, extension, restriction, sequence
  1543. attributes:
  1544. id -- ID
  1545. ref -- NCName, required
  1546. contents:
  1547. annotation?
  1548. """
  1549. required = ['ref']
  1550. attributes = {'id':None,
  1551. 'ref':None}
  1552. contents = {'xsd':['annotation']}
  1553. def __init__(self, parent):
  1554. XMLSchemaComponent.__init__(self, parent)
  1555. self.annotation = None
  1556. def fromDom(self, node):
  1557. self.setAttributes(node)
  1558. contents = self.getContents(node)
  1559. for i in contents:
  1560. component = SplitQName(i.getTagName())[1]
  1561. if component in self.__class__.contents['xsd']:
  1562. if component == 'annotation' and not self.annotation:
  1563. self.annotation = Annotation()
  1564. self.annotation.fromDom(i)
  1565. else:
  1566. raise SchemaError, 'Unknown component (%s)' %(i.getTagName())
  1567. else:
  1568. raise SchemaError, 'Unknown component (%s)' %(i.getTagName())
  1569. class ComplexType(XMLSchemaComponent,\
  1570. MarkerInterface,\
  1571. DefinitionMarker,\
  1572. ComplexMarker):
  1573. """<complexType name>
  1574. parents:
  1575. redefine, schema
  1576. attributes:
  1577. id -- ID
  1578. name -- NCName, required
  1579. mixed -- boolean, false
  1580. abstract -- boolean, false
  1581. block -- ('#all' | ('extension' | 'restriction')*), schema.blockDefault
  1582. final -- ('#all' | ('extension' | 'restriction')*), schema.finalDefault
  1583. contents:
  1584. annotation?, (simpleContent | complexContent |
  1585. ((group | all | choice | sequence)?, (attribute | attributeGroup)*, anyAttribute?))
  1586. """
  1587. required = ['name']
  1588. attributes = {'id':None,
  1589. 'name':None,
  1590. 'mixed':0,
  1591. 'abstract':0,
  1592. 'block':lambda: self._parent.parent().getBlockDefault(),
  1593. 'final':lambda: self._parent.parent().getFinalDefault()}
  1594. contents = {'xsd':['annotation', 'simpleContent', 'complexContent',\
  1595. 'group', 'all', 'choice', 'sequence', 'attribute', 'attributeGroup',\
  1596. 'anyAttribute', 'any']}
  1597. def __init__(self, parent):
  1598. XMLSchemaComponent.__init__(self, parent)
  1599. self.annotation = None
  1600. self.content = None
  1601. self.attr_content = None
  1602. def fromDom(self, node):
  1603. self.setAttributes(node)
  1604. contents = self.getContents(node)
  1605. indx = 0
  1606. num = len(contents)
  1607. #XXX ugly
  1608. if not num:
  1609. return
  1610. component = SplitQName(contents[indx].getTagName())[1]
  1611. if component == 'annotation':
  1612. self.annotation = Annotation()
  1613. self.annotation.fromDom(contents[indx])
  1614. indx += 1
  1615. component = SplitQName(contents[indx].getTagName())[1]
  1616. self.content = None
  1617. if component == 'simpleContent':
  1618. self.content = self.__class__.SimpleContent(self)
  1619. self.content.fromDom(contents[indx])
  1620. elif component == 'complexContent':
  1621. self.content = self.__class__.ComplexContent(self)
  1622. self.content.fromDom(contents[indx])
  1623. else:
  1624. if component == 'all':
  1625. self.content = All(self)
  1626. elif component == 'choice':
  1627. self.content = Choice(self)
  1628. elif component == 'sequence':
  1629. self.content = Sequence(self)
  1630. elif component == 'group':
  1631. self.content = ModelGroupReference(self)
  1632. if self.content:
  1633. self.content.fromDom(contents[indx])
  1634. indx += 1
  1635. self.attr_content = []
  1636. while indx < num:
  1637. component = SplitQName(contents[indx].getTagName())[1]
  1638. if component == 'attribute':
  1639. if contents[indx].hasattr('ref'):
  1640. self.attr_content.append(AttributeReference(self))
  1641. else:
  1642. self.attr_content.append(LocalAttributeDeclaration(self))
  1643. elif component == 'attributeGroup':
  1644. self.attr_content.append(AttributeGroupDefinition(self))
  1645. elif component == 'anyAttribute':
  1646. self.attr_content.append(AttributeWildCard(self))
  1647. else:
  1648. raise SchemaError, 'Unknown component (%s)' %(contents[indx].getTagName())
  1649. self.attr_content[-1].fromDom(contents[indx])
  1650. indx += 1
  1651. class _DerivedType(XMLSchemaComponent):
  1652. def __init__(self, parent):
  1653. XMLSchemaComponent.__init__(self, parent)
  1654. self.annotation = None
  1655. self.derivation = None
  1656. def fromDom(self, node):
  1657. self.setAttributes(node)
  1658. contents = self.getContents(node)
  1659. for i in contents:
  1660. component = SplitQName(i.getTagName())[1]
  1661. if component in self.__class__.contents['xsd']:
  1662. if component == 'annotation' and not self.annotation:
  1663. self.annotation = Annotation()
  1664. self.annotation.fromDom(i)
  1665. continue
  1666. elif component == 'restriction' and not self.derivation:
  1667. self.derivation = self.__class__.Restriction(self)
  1668. elif component == 'extension' and not self.derivation:
  1669. self.derivation = self.__class__.Extension(self)
  1670. else:
  1671. raise SchemaError, 'Unknown component (%s)' %(i.getTagName())
  1672. else:
  1673. raise SchemaError, 'Unknown component (%s)' %(i.getTagName())
  1674. self.derivation.fromDom(i)
  1675. class ComplexContent(_DerivedType,\
  1676. MarkerInterface,\
  1677. ComplexMarker):
  1678. """<complexContent>
  1679. parents:
  1680. complexType
  1681. attributes:
  1682. id -- ID
  1683. mixed -- boolean, false
  1684. contents:
  1685. annotation?, (restriction | extension)
  1686. """
  1687. attributes = {'id':None,
  1688. 'mixed':0 }
  1689. contents = {'xsd':['annotation', 'restriction', 'extension']}
  1690. class _DerivationBase(XMLSchemaComponent):
  1691. """<extension>,<restriction>
  1692. parents:
  1693. complexContent
  1694. attributes:
  1695. id -- ID
  1696. base -- QName, required
  1697. contents:
  1698. annotation?, (group | all | choice | sequence)?,
  1699. (attribute | attributeGroup)*, anyAttribute?
  1700. """
  1701. required = ['base']
  1702. attributes = {'id':None,
  1703. 'base':None }
  1704. contents = {'xsd':['annotation', 'group', 'all', 'choice',\
  1705. 'sequence', 'attribute', 'attributeGroup', 'anyAttribute']}
  1706. def fromDom(self, node):
  1707. self.setAttributes(node)
  1708. contents = self.getContents(node)
  1709. indx = 0
  1710. num = len(contents)
  1711. #XXX ugly
  1712. if not num:
  1713. return
  1714. component = SplitQName(contents[indx].getTagName())[1]
  1715. if component == 'annotation':
  1716. self.annotation = Annotation()
  1717. self.annotation.fromDom(contents[indx])
  1718. indx += 1
  1719. component = SplitQName(contents[indx].getTagName())[1]
  1720. if component == 'all':
  1721. self.content = All(self)
  1722. elif component == 'choice':
  1723. self.content = Choice(self)
  1724. elif component == 'sequence':
  1725. self.content = Sequence(self)
  1726. elif component == 'group':
  1727. self.content = ModelGroupReference(self)
  1728. else:
  1729. raise SchemaError, 'Unknown component (%s)' %(contents[indx].getTagName())
  1730. self.content.fromDom(contents[indx])
  1731. indx += 1
  1732. self.attr_content = []
  1733. while indx < num:
  1734. component = SplitQName(contents[indx].getTagName())[1]
  1735. if component == 'attribute':
  1736. if contents[indx].hasattr('ref'):
  1737. self.attr_content.append(AttributeReference(self))
  1738. else:
  1739. self.attr_content.append(LocalAttributeDeclaration(self))
  1740. elif component == 'attributeGroup':
  1741. self.attr_content.append(AttributeGroupDefinition(self))
  1742. elif component == 'anyAttribute':
  1743. self.attr_content.append(AttributeWildCard(self))
  1744. else:
  1745. raise SchemaError, 'Unknown component (%s)' %(contents[indx].getTagName())
  1746. self.attr_content[-1].fromDom(contents[indx])
  1747. indx += 1
  1748. class Extension(_DerivationBase, MarkerInterface, ExtensionMarker):
  1749. """<extension base>
  1750. parents:
  1751. complexContent
  1752. attributes:
  1753. id -- ID
  1754. base -- QName, required
  1755. contents:
  1756. annotation?, (group | all | choice | sequence)?,
  1757. (attribute | attributeGroup)*, anyAttribute?
  1758. """
  1759. pass
  1760. class Restriction(_DerivationBase,\
  1761. MarkerInterface,\
  1762. RestrictionMarker):
  1763. """<restriction base>
  1764. parents:
  1765. complexContent
  1766. attributes:
  1767. id -- ID
  1768. base -- QName, required
  1769. contents:
  1770. annotation?, (group | all | choice | sequence)?,
  1771. (attribute | attributeGroup)*, anyAttribute?
  1772. """
  1773. pass
  1774. class SimpleContent(_DerivedType,\
  1775. MarkerInterface,\
  1776. SimpleMarker):
  1777. """<simpleContent>
  1778. parents:
  1779. complexType
  1780. attributes:
  1781. id -- ID
  1782. contents:
  1783. annotation?, (restriction | extension)
  1784. """
  1785. attributes = {'id':None}
  1786. contents = {'xsd':['annotation', 'restriction', 'extension']}
  1787. class Extension(XMLSchemaComponent,\
  1788. MarkerInterface,\
  1789. ExtensionMarker):
  1790. """<extension base>
  1791. parents:
  1792. simpleContent
  1793. attributes:
  1794. id -- ID
  1795. base -- QName, required
  1796. contents:
  1797. annotation?, (group | all | choice | sequence)?,
  1798. (attribute | attributeGroup)*, anyAttribute?
  1799. """
  1800. required = ['base']
  1801. attributes = {'id':None,
  1802. 'base':None }
  1803. contents = {'xsd':['annotation', 'group', 'all', 'choice',\
  1804. 'sequence', 'attribute', 'attributeGroup', 'anyAttribute']}
  1805. def fromDom(self, node):
  1806. self.setAttributes(node)
  1807. contents = self.getContents(node)
  1808. indx = 0
  1809. num = len(contents)
  1810. component = SplitQName(contents[indx].getTagName())[1]
  1811. if component == 'annotation':
  1812. self.annotation = Annotation()
  1813. self.annotation.fromDom(contents[indx])
  1814. indx += 1
  1815. component = SplitQName(contents[indx].getTagName())[1]
  1816. if component == 'all':
  1817. self.content = All(self)
  1818. elif component == 'choice':
  1819. self.content = Choice(self)
  1820. elif component == 'sequence':
  1821. self.content = Sequence(self)
  1822. elif component == 'group':
  1823. self.content = ModelGroupReference(self)
  1824. else:
  1825. raise SchemaError, 'Unknown component (%s)' %(contents[indx].getTagName())
  1826. self.content.fromDom(contents[indx])
  1827. indx += 1
  1828. self.attr_content = []
  1829. while indx < num:
  1830. component = SplitQName(contents[indx].getTagName())[1]
  1831. if component == 'attribute':
  1832. if contents[indx].hasattr('ref'):
  1833. self.attr_content.append(AttributeReference(self))
  1834. else:
  1835. self.attr_content.append(LocalAttributeDeclaration(self))
  1836. elif component == 'attributeGroup':
  1837. self.attr_content.append(AttributeGroupDefinition(self))
  1838. elif component == 'anyAttribute':
  1839. self.attr_content.append(AttributeWildCard(self))
  1840. else:
  1841. raise SchemaError, 'Unknown component (%s)' %(contents[indx].getTagName())
  1842. self.attr_content[-1].fromDom(contents[indx])
  1843. indx += 1
  1844. class Restriction(XMLSchemaComponent,\
  1845. MarkerInterface,\
  1846. RestrictionMarker):
  1847. """<restriction base>
  1848. parents:
  1849. simpleContent
  1850. attributes:
  1851. id -- ID
  1852. base -- QName, required
  1853. contents:
  1854. annotation?, simpleType?, (enumeration | length |
  1855. maxExclusive | maxInclusive | maxLength | minExclusive |
  1856. minInclusive | minLength | pattern | fractionDigits |
  1857. totalDigits | whiteSpace)*, (attribute | attributeGroup)*,
  1858. anyAttribute?
  1859. """
  1860. required = ['base']
  1861. attributes = {'id':None,
  1862. 'base':None }
  1863. contents = {'xsd':['annotation', 'simpleType', 'attribute',\
  1864. 'attributeGroup', 'anyAttribute'] + RestrictionMarker.facets}
  1865. class LocalComplexType(ComplexType):
  1866. """<complexType>
  1867. parents:
  1868. element
  1869. attributes:
  1870. id -- ID
  1871. mixed -- boolean, false
  1872. contents:
  1873. annotation?, (simpleContent | complexContent |
  1874. ((group | all | choice | sequence)?, (attribute | attributeGroup)*, anyAttribute?))
  1875. """
  1876. required = []
  1877. attributes = {'id':None,
  1878. 'mixed':0}
  1879. class SimpleType(XMLSchemaComponent,\
  1880. MarkerInterface,\
  1881. DefinitionMarker,\
  1882. SimpleMarker):
  1883. """<simpleType name>
  1884. parents:
  1885. redefine, schema
  1886. attributes:
  1887. id -- ID
  1888. name -- NCName, required
  1889. final -- ('#all' | ('extension' | 'restriction' | 'list' | 'union')*),
  1890. schema.finalDefault
  1891. contents:
  1892. annotation?, (restriction | list | union)
  1893. """
  1894. required = ['name']
  1895. attributes = {'id':None,
  1896. 'name':None,
  1897. 'final':lambda: self._parent.parent().getFinalDefault()}
  1898. contents = {'xsd':['annotation', 'restriction', 'list', 'union']}
  1899. def __init__(self, parent):
  1900. XMLSchemaComponent.__init__(self, parent)
  1901. self.annotation = None
  1902. self.content = None
  1903. self.attr_content = None
  1904. def setType(self, qname, namespace):
  1905. self.type = TypeDescriptionComponent(namespace, qname)
  1906. def fromDom(self, node):
  1907. self.setAttributes(node)
  1908. contents = self.getContents(node)
  1909. for child in contents:
  1910. component = SplitQName(child.getTagName())[1]
  1911. if component == 'annotation':
  1912. self.annotation = Annotation()
  1913. self.annotation.fromDom(child)
  1914. break
  1915. else:
  1916. return
  1917. if component == 'restriction':
  1918. self.content = self.__class__.Restriction(self)
  1919. elif component == 'list':
  1920. self.content = self.__class__.List(self)
  1921. elif component == 'union':
  1922. self.content = self.__class__.Union(self)
  1923. else:
  1924. raise SchemaError, 'Unknown component (%s)' %(contents[indx].getTagName())
  1925. self.content.fromDom(child)
  1926. class Restriction(XMLSchemaComponent,\
  1927. MarkerInterface,\
  1928. RestrictionMarker):
  1929. """<restriction base>
  1930. parents:
  1931. simpleType
  1932. attributes:
  1933. id -- ID
  1934. base -- QName, required or simpleType child
  1935. contents:
  1936. annotation?, simpleType?, (enumeration | length |
  1937. maxExclusive | maxInclusive | maxLength | minExclusive |
  1938. minInclusive | minLength | pattern | fractionDigits |
  1939. totalDigits | whiteSpace)*
  1940. """
  1941. attributes = {'id':None,
  1942. 'base':None }
  1943. contents = {'xsd':['annotation', 'simpleType']+RestrictionMarker.facets}
  1944. def __init__(self, parent):
  1945. XMLSchemaComponent.__init__(self, parent)
  1946. self.annotation = None
  1947. self.content = None
  1948. self.attr_content = None
  1949. def fromDom(self, node):
  1950. self.setAttributes(node)
  1951. contents = self.getContents(node)
  1952. self.content = []
  1953. self.attr_content = []
  1954. for indx in range(len(contents)):
  1955. component = SplitQName(contents[indx].getTagName())[1]
  1956. if (component == 'annotation') and (not indx):
  1957. self.annotation = Annotation()
  1958. self.annotation.fromDom(contents[indx])
  1959. continue
  1960. elif (component == 'simpleType') and (not indx or indx == 1):
  1961. self.content.append(SimpleType(self))
  1962. self.content[-1].fromDom(contents[indx])
  1963. elif component in RestrictionMarker.facets:
  1964. #print_debug('%s class instance, skipping %s' %(self.__class__, component))
  1965. pass
  1966. else:
  1967. raise SchemaError, 'Unknown component (%s)' %(i.getTagName())
  1968. class Union(XMLSchemaComponent):
  1969. """<union>
  1970. parents:
  1971. simpleType
  1972. attributes:
  1973. id -- ID
  1974. memberTypes -- list of QNames, required or simpleType child.
  1975. contents:
  1976. annotation?, simpleType*
  1977. """
  1978. attributes = {'id':None,
  1979. 'memberTypes':None }
  1980. contents = {'xsd':['annotation', 'simpleType']}
  1981. class List(XMLSchemaComponent):
  1982. """<union>
  1983. parents:
  1984. simpleType
  1985. attributes:
  1986. id -- ID
  1987. itemType -- QName, required or simpleType child.
  1988. contents:
  1989. annotation?, simpleType?
  1990. """
  1991. attributes = {'id':None,
  1992. 'memberTypes':None }
  1993. contents = {'xsd':['annotation', 'simpleType']}
  1994. class AnonymousSimpleType(SimpleType,\
  1995. MarkerInterface,\
  1996. SimpleMarker):
  1997. """<simpleType>
  1998. parents:
  1999. attribute, element, list, restriction, union
  2000. attributes:
  2001. id -- ID
  2002. contents:
  2003. annotation?, (restriction | list | union)
  2004. """
  2005. required = []
  2006. attributes = {'id':None}
  2007. class Redefine:
  2008. """<redefine>
  2009. parents:
  2010. attributes:
  2011. contents:
  2012. """
  2013. pass
  2014. ###########################
  2015. ###########################
  2016. class TypeDescriptionComponent(tuple):
  2017. """Tuple of length 2, consisting of
  2018. a namespace and unprefixed name.
  2019. """
  2020. def __init__(self, args):
  2021. """args -- (namespace, name)
  2022. Remove the name's prefix, irrelevant.
  2023. """
  2024. if len(args) != 2:
  2025. raise TypeError, 'expecting tuple (namespace, name), got %s' %args
  2026. elif args[1].find(':') >= 0:
  2027. args = (args[0], SplitQName(args[1])[1])
  2028. tuple.__init__(self, args)
  2029. return
  2030. def getTargetNamespace(self):
  2031. return self[0]
  2032. def getName(self):
  2033. return self[1]
  2034. '''
  2035. import string, types, base64, re
  2036. from Utility import DOM, Collection
  2037. from StringIO import StringIO
  2038. class SchemaReader:
  2039. """A SchemaReader creates XMLSchema objects from urls and xml data."""
  2040. def loadFromStream(self, file):
  2041. """Return an XMLSchema instance loaded from a file object."""
  2042. document = DOM.loadDocument(file)
  2043. schema = XMLSchema()
  2044. schema.load(document)
  2045. return schema
  2046. def loadFromString(self, data):
  2047. """Return an XMLSchema instance loaded from an xml string."""
  2048. return self.loadFromStream(StringIO(data))
  2049. def loadFromURL(self, url):
  2050. """Return an XMLSchema instance loaded from the given url."""
  2051. document = DOM.loadFromURL(url)
  2052. schema = XMLSchema()
  2053. schema.location = url
  2054. schema.load(document)
  2055. return schema
  2056. def loadFromFile(self, filename):
  2057. """Return an XMLSchema instance loaded from the given file."""
  2058. file = open(filename, 'rb')
  2059. try: schema = self.loadFromStream(file)
  2060. finally: file.close()
  2061. return schema
  2062. class SchemaError(Exception):
  2063. pass
  2064. class XMLSchema:
  2065. # This is temporary, for the benefit of WSDL until the real thing works.
  2066. def __init__(self, element):
  2067. self.targetNamespace = DOM.getAttr(element, 'targetNamespace')
  2068. self.element = element
  2069. class realXMLSchema:
  2070. """A schema is a collection of schema components derived from one
  2071. or more schema documents, that is, one or more <schema> element
  2072. information items. It represents the abstract notion of a schema
  2073. rather than a single schema document (or other representation)."""
  2074. def __init__(self):
  2075. self.simpleTypes = Collection(self)
  2076. self.complexTypes = Collection(self)
  2077. self.attributes = Collection(self)
  2078. self.elements = Collection(self)
  2079. self.attrGroups = Collection(self)
  2080. self.idConstraints=None
  2081. self.modelGroups = None
  2082. self.notations = None
  2083. self.extensions = []
  2084. targetNamespace = None
  2085. attributeFormDefault = 'unqualified'
  2086. elementFormDefault = 'unqualified'
  2087. blockDefault = None
  2088. finalDefault = None
  2089. location = None
  2090. version = None
  2091. id = None
  2092. def load(self, document):
  2093. if document.nodeType == document.DOCUMENT_NODE:
  2094. schema = DOM.getElement(document, 'schema', None, None)
  2095. else:
  2096. schema = document
  2097. if schema is None:
  2098. raise SchemaError('Missing <schema> element.')
  2099. self.namespace = namespace = schema.namespaceURI
  2100. if not namespace in DOM.NS_XSD_ALL:
  2101. raise SchemaError(
  2102. 'Unknown XML schema namespace: %s.' % self.namespace
  2103. )
  2104. for attrname in (
  2105. 'targetNamespace', 'attributeFormDefault', 'elementFormDefault',
  2106. 'blockDefault', 'finalDefault', 'version', 'id'
  2107. ):
  2108. value = DOM.getAttr(schema, attrname, None, None)
  2109. if value is not None:
  2110. setattr(self, attrname, value)
  2111. # Resolve imports and includes here?
  2112. ## imported = {}
  2113. ## while 1:
  2114. ## imports = []
  2115. ## for element in DOM.getElements(definitions, 'import', NS_WSDL):
  2116. ## location = DOM.getAttr(element, 'location')
  2117. ## if not imported.has_key(location):
  2118. ## imports.append(element)
  2119. ## if not imports:
  2120. ## break
  2121. ## for element in imports:
  2122. ## self._import(document, element)
  2123. ## imported[location] = 1
  2124. for element in DOM.getElements(schema, None, None):
  2125. localName = element.localName
  2126. if not DOM.nsUriMatch(element.namespaceURI, namespace):
  2127. self.extensions.append(element)
  2128. continue
  2129. elif localName == 'message':
  2130. name = DOM.getAttr(element, 'name')
  2131. docs = GetDocumentation(element)
  2132. message = self.addMessage(name, docs)
  2133. parts = DOM.getElements(element, 'part', NS_WSDL)
  2134. message.load(parts)
  2135. continue
  2136. def _import(self, document, element):
  2137. namespace = DOM.getAttr(element, 'namespace', default=None)
  2138. location = DOM.getAttr(element, 'location', default=None)
  2139. if namespace is None or location is None:
  2140. raise WSDLError(
  2141. 'Invalid import element (missing namespace or location).'
  2142. )
  2143. # Sort-of support relative locations to simplify unit testing. The
  2144. # WSDL specification actually doesn't allow relative URLs, so its
  2145. # ok that this only works with urls relative to the initial document.
  2146. location = urllib.basejoin(self.location, location)
  2147. obimport = self.addImport(namespace, location)
  2148. obimport._loaded = 1
  2149. importdoc = DOM.loadFromURL(location)
  2150. try:
  2151. if location.find('#') > -1:
  2152. idref = location.split('#')[-1]
  2153. imported = DOM.getElementById(importdoc, idref)
  2154. else:
  2155. imported = importdoc.documentElement
  2156. if imported is None:
  2157. raise WSDLError(
  2158. 'Import target element not found for: %s' % location
  2159. )
  2160. imported_tns = DOM.getAttr(imported, 'targetNamespace')
  2161. importer_tns = namespace
  2162. if imported_tns != importer_tns:
  2163. return
  2164. if imported.localName == 'definitions':
  2165. imported_nodes = imported.childNodes
  2166. else:
  2167. imported_nodes = [imported]
  2168. parent = element.parentNode
  2169. for node in imported_nodes:
  2170. if node.nodeType != node.ELEMENT_NODE:
  2171. continue
  2172. child = DOM.importNode(document, node, 1)
  2173. parent.appendChild(child)
  2174. child.setAttribute('targetNamespace', importer_tns)
  2175. attrsNS = imported._attrsNS
  2176. for attrkey in attrsNS.keys():
  2177. if attrkey[0] == DOM.NS_XMLNS:
  2178. attr = attrsNS[attrkey].cloneNode(1)
  2179. child.setAttributeNode(attr)
  2180. finally:
  2181. importdoc.unlink()
  2182. class Element:
  2183. """Common base class for element representation classes."""
  2184. def __init__(self, name=None, documentation=''):
  2185. self.name = name
  2186. self.documentation = documentation
  2187. self.extensions = []
  2188. def addExtension(self, item):
  2189. self.extensions.append(item)
  2190. class SimpleTypeDefinition:
  2191. """Represents an xml schema simple type definition."""
  2192. class ComplexTypeDefinition:
  2193. """Represents an xml schema complex type definition."""
  2194. class AttributeDeclaration:
  2195. """Represents an xml schema attribute declaration."""
  2196. class ElementDeclaration:
  2197. """Represents an xml schema element declaration."""
  2198. def __init__(self, name, type=None, targetNamespace=None):
  2199. self.name = name
  2200. targetNamespace = None
  2201. annotation = None
  2202. nillable = 0
  2203. abstract = 0
  2204. default = None
  2205. fixed = None
  2206. scope = 'global'
  2207. type = None
  2208. form = 0
  2209. # Things we will not worry about for now.
  2210. id_constraint_defs = None
  2211. sub_group_exclude = None
  2212. sub_group_affils = None
  2213. disallowed_subs = None
  2214. class AttributeGroupDefinition:
  2215. """Represents an xml schema attribute group definition."""
  2216. class IdentityConstraintDefinition:
  2217. """Represents an xml schema identity constraint definition."""
  2218. class ModelGroupDefinition:
  2219. """Represents an xml schema model group definition."""
  2220. class NotationDeclaration:
  2221. """Represents an xml schema notation declaration."""
  2222. class Annotation:
  2223. """Represents an xml schema annotation."""
  2224. class ModelGroup:
  2225. """Represents an xml schema model group."""
  2226. class Particle:
  2227. """Represents an xml schema particle."""
  2228. class WildCard:
  2229. """Represents an xml schema wildcard."""
  2230. class AttributeUse:
  2231. """Represents an xml schema attribute use."""
  2232. class ElementComponent:
  2233. namespace = ''
  2234. name = ''
  2235. type = None
  2236. form = 'qualified | unqualified'
  2237. scope = 'global or complex def'
  2238. constraint = ('value', 'default | fixed')
  2239. nillable = 0
  2240. id_constraint_defs = None
  2241. sub_group_affil = None
  2242. sub_group_exclusions = None
  2243. disallowed_subs = 'substitution, extension, restriction'
  2244. abstract = 0
  2245. minOccurs = 1
  2246. maxOccurs = 1
  2247. ref = ''
  2248. class AttributeThing:
  2249. name = ''
  2250. namespace = ''
  2251. typeName = ''
  2252. typeUri = ''
  2253. scope = 'global | local to complex def'
  2254. constraint = ('value:default', 'value:fixed')
  2255. use = 'optional | prohibited | required'
  2256. class ElementDataType:
  2257. namespace = ''
  2258. name = ''
  2259. element_form = 'qualified | unqualified'
  2260. attr_form = None
  2261. type_name = ''
  2262. type_uri = ''
  2263. def __init__(self, name, namespace, type_name, type_uri):
  2264. self.namespace = namespace
  2265. self.name = name
  2266. # type may be anonymous...
  2267. self.type_name = type_name
  2268. self.type_uri = type_uri
  2269. def checkValue(self, value, context):
  2270. # Delegate value checking to the type of the element.
  2271. typeref = (self.type_uri, self.type_name)
  2272. handler = context.serializer.getType(typeref)
  2273. return handler.checkValue(value, context)
  2274. def serialize(self, name, namespace, value, context, **kwargs):
  2275. if context.check_values:
  2276. self.checkValue(value, context)
  2277. # Delegate serialization to the type of the element.
  2278. typeref = (self.type_uri, self.type_name)
  2279. handler = context.serializer.getType(typeref)
  2280. return handler.serialize(self.name, self.namespace, value, context)
  2281. def deserialize(self, element, context):
  2282. if element_is_null(element, context):
  2283. return None
  2284. # Delegate deserialization to the type of the element.
  2285. typeref = (self.type_uri, self.type_name)
  2286. handler = context.serializer.getType(typeref)
  2287. return handler.deserialize(element, context)
  2288. def parse_schema(data):
  2289. targetNS = ''
  2290. attributeFormDefault = 0
  2291. elementFormDefault = 0
  2292. blockDefault = ''
  2293. finalDefault = ''
  2294. language = None
  2295. version = None
  2296. id = ''
  2297. '''