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.
 
 
 

3126 lines
107 KiB

  1. #!/usr/bin/env python
  2. # Copyright (c) 2003, The Regents of the University of California,
  3. # through Lawrence Berkeley National Laboratory (subject to receipt of
  4. # any required approvals from the U.S. Dept. of Energy). All rights
  5. # reserved.
  6. #
  7. # Copyright (c) 2001 Zope Corporation and Contributors. All Rights Reserved.
  8. #
  9. # This software is subject to the provisions of the Zope Public License,
  10. # Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution.
  11. # THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
  12. # WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  13. # WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
  14. # FOR A PARTICULAR PURPOSE.
  15. ident = "$Id$"
  16. import types
  17. import weakref
  18. import sys
  19. import warnings
  20. import logging
  21. from Namespaces import SCHEMA, XMLNS, SOAP, APACHE
  22. from Utility import DOM, DOMException, Collection, SplitQName, basejoin
  23. try:
  24. from io import StringIO
  25. except ImportError:
  26. from cStringIO import StringIO
  27. # If we have no threading, this should be a no-op
  28. try:
  29. from threading import RLock
  30. except ImportError:
  31. class RLock:
  32. def acquire():
  33. pass
  34. def release():
  35. pass
  36. #
  37. # Collections in XMLSchema class
  38. #
  39. TYPES = 'types'
  40. ATTRIBUTE_GROUPS = 'attr_groups'
  41. ATTRIBUTES = 'attr_decl'
  42. ELEMENTS = 'elements'
  43. MODEL_GROUPS = 'model_groups'
  44. BUILT_IN_NAMESPACES = [SOAP.ENC, ] + SCHEMA.XSD_LIST + [APACHE.AXIS_NS]
  45. def GetSchema(component):
  46. """convience function for finding the parent XMLSchema instance.
  47. """
  48. parent = component
  49. while not isinstance(parent, XMLSchema):
  50. parent = parent._parent()
  51. return parent
  52. class SchemaReader:
  53. """A SchemaReader creates XMLSchema objects from urls and xml data.
  54. """
  55. namespaceToSchema = {}
  56. def __init__(self, domReader=None, base_url=None):
  57. """domReader -- class must implement DOMAdapterInterface
  58. base_url -- base url string
  59. """
  60. self.__base_url = base_url
  61. self.__readerClass = domReader
  62. if not self.__readerClass:
  63. self.__readerClass = DOMAdapter
  64. self._includes = {}
  65. self._imports = {}
  66. def __setImports(self, schema):
  67. """Add dictionary of imports to schema instance.
  68. schema -- XMLSchema instance
  69. """
  70. for ns, val in schema.imports.items():
  71. if ns in self._imports:
  72. schema.addImportSchema(self._imports[ns])
  73. def __setIncludes(self, schema):
  74. """Add dictionary of includes to schema instance.
  75. schema -- XMLSchema instance
  76. """
  77. for schemaLocation, val in schema.includes.items():
  78. if schemaLocation in self._includes:
  79. schema.addIncludeSchema(schemaLocation, self._imports[schemaLocation])
  80. def addSchemaByLocation(self, location, schema):
  81. """provide reader with schema document for a location.
  82. """
  83. self._includes[location] = schema
  84. def addSchemaByNamespace(self, schema):
  85. """provide reader with schema document for a targetNamespace.
  86. """
  87. self._imports[schema.targetNamespace] = schema
  88. def loadFromNode(self, parent, element):
  89. """element -- DOM node or document
  90. parent -- WSDLAdapter instance
  91. """
  92. reader = self.__readerClass(element)
  93. schema = XMLSchema(parent)
  94. #HACK to keep a reference
  95. schema.wsdl = parent
  96. schema.setBaseUrl(self.__base_url)
  97. schema.load(reader)
  98. return schema
  99. def loadFromStream(self, file, url=None):
  100. """Return an XMLSchema instance loaded from a file object.
  101. file -- file object
  102. url -- base location for resolving imports/includes.
  103. """
  104. reader = self.__readerClass()
  105. reader.loadDocument(file)
  106. schema = XMLSchema()
  107. if url is not None:
  108. schema.setBaseUrl(url)
  109. schema.load(reader)
  110. self.__setIncludes(schema)
  111. self.__setImports(schema)
  112. return schema
  113. def loadFromString(self, data):
  114. """Return an XMLSchema instance loaded from an XML string.
  115. data -- XML string
  116. """
  117. return self.loadFromStream(StringIO(data))
  118. def loadFromURL(self, url, schema=None):
  119. """Return an XMLSchema instance loaded from the given url.
  120. url -- URL to dereference
  121. schema -- Optional XMLSchema instance.
  122. """
  123. reader = self.__readerClass()
  124. if self.__base_url:
  125. url = basejoin(self.__base_url, url)
  126. reader.loadFromURL(url)
  127. schema = schema or XMLSchema()
  128. schema.setBaseUrl(url)
  129. schema.load(reader)
  130. self.__setIncludes(schema)
  131. self.__setImports(schema)
  132. return schema
  133. def loadFromFile(self, filename):
  134. """Return an XMLSchema instance loaded from the given file.
  135. filename -- name of file to open
  136. """
  137. if self.__base_url:
  138. filename = basejoin(self.__base_url, filename)
  139. file = open(filename, 'rb')
  140. try:
  141. schema = self.loadFromStream(file, filename)
  142. finally:
  143. file.close()
  144. return schema
  145. class SchemaError(Exception):
  146. pass
  147. class NoSchemaLocationWarning(Exception):
  148. pass
  149. ###########################
  150. # DOM Utility Adapters
  151. ##########################
  152. class DOMAdapterInterface:
  153. def hasattr(self, attr, ns=None):
  154. """return true if node has attribute
  155. attr -- attribute to check for
  156. ns -- namespace of attribute, by default None
  157. """
  158. raise NotImplementedError('adapter method not implemented')
  159. def getContentList(self, *contents):
  160. """returns an ordered list of child nodes
  161. *contents -- list of node names to return
  162. """
  163. raise NotImplementedError('adapter method not implemented')
  164. def setAttributeDictionary(self, attributes):
  165. """set attribute dictionary
  166. """
  167. raise NotImplementedError('adapter method not implemented')
  168. def getAttributeDictionary(self):
  169. """returns a dict of node's attributes
  170. """
  171. raise NotImplementedError('adapter method not implemented')
  172. def getNamespace(self, prefix):
  173. """returns namespace referenced by prefix.
  174. """
  175. raise NotImplementedError('adapter method not implemented')
  176. def getTagName(self):
  177. """returns tagName of node
  178. """
  179. raise NotImplementedError('adapter method not implemented')
  180. def getParentNode(self):
  181. """returns parent element in DOMAdapter or None
  182. """
  183. raise NotImplementedError('adapter method not implemented')
  184. def loadDocument(self, file):
  185. """load a Document from a file object
  186. file --
  187. """
  188. raise NotImplementedError('adapter method not implemented')
  189. def loadFromURL(self, url):
  190. """load a Document from an url
  191. url -- URL to dereference
  192. """
  193. raise NotImplementedError('adapter method not implemented')
  194. class DOMAdapter(DOMAdapterInterface):
  195. """Adapter for ZSI.Utility.DOM
  196. """
  197. def __init__(self, node=None):
  198. """Reset all instance variables.
  199. element -- DOM document, node, or None
  200. """
  201. if hasattr(node, 'documentElement'):
  202. self.__node = node.documentElement
  203. else:
  204. self.__node = node
  205. self.__attributes = None
  206. def getNode(self):
  207. return self.__node
  208. def hasattr(self, attr, ns=None):
  209. """attr -- attribute
  210. ns -- optional namespace, None means unprefixed attribute.
  211. """
  212. if not self.__attributes:
  213. self.setAttributeDictionary()
  214. if ns:
  215. return attr in self.__attributes.get(ns, {})
  216. return attr in self.__attributes
  217. def getContentList(self, *contents):
  218. nodes = []
  219. ELEMENT_NODE = self.__node.ELEMENT_NODE
  220. for child in DOM.getElements(self.__node, None):
  221. if child.nodeType == ELEMENT_NODE and\
  222. SplitQName(child.tagName)[1] in contents:
  223. nodes.append(child)
  224. return map(self.__class__, nodes)
  225. def setAttributeDictionary(self):
  226. self.__attributes = {}
  227. for v in self.__node._attrs.values():
  228. self.__attributes[v.nodeName] = v.nodeValue
  229. def getAttributeDictionary(self):
  230. if not self.__attributes:
  231. self.setAttributeDictionary()
  232. return self.__attributes
  233. def getTagName(self):
  234. return self.__node.tagName
  235. def getParentNode(self):
  236. if self.__node.parentNode.nodeType == self.__node.ELEMENT_NODE:
  237. return DOMAdapter(self.__node.parentNode)
  238. return None
  239. def getNamespace(self, prefix):
  240. """prefix -- deference namespace prefix in node's context.
  241. Ascends parent nodes until found.
  242. """
  243. namespace = None
  244. if prefix == 'xmlns':
  245. namespace = DOM.findDefaultNS(prefix, self.__node)
  246. else:
  247. try:
  248. namespace = DOM.findNamespaceURI(prefix, self.__node)
  249. except DOMException as ex:
  250. if prefix != 'xml':
  251. raise SchemaError('%s namespace not declared for %s' % (prefix, self.__node._get_tagName()))
  252. namespace = XMLNS.XML
  253. return namespace
  254. def loadDocument(self, file):
  255. self.__node = DOM.loadDocument(file)
  256. if hasattr(self.__node, 'documentElement'):
  257. self.__node = self.__node.documentElement
  258. def loadFromURL(self, url):
  259. self.__node = DOM.loadFromURL(url)
  260. if hasattr(self.__node, 'documentElement'):
  261. self.__node = self.__node.documentElement
  262. class XMLBase:
  263. """ These class variables are for string indentation.
  264. """
  265. tag = None
  266. __indent = 0
  267. __rlock = RLock()
  268. def __str__(self):
  269. XMLBase.__rlock.acquire()
  270. XMLBase.__indent += 1
  271. tmp = "<" + str(self.__class__) + '>\n'
  272. for k, v in self.__dict__.items():
  273. tmp += "%s* %s = %s\n" % (XMLBase.__indent * ' ', k, v)
  274. XMLBase.__indent -= 1
  275. XMLBase.__rlock.release()
  276. return tmp
  277. """Marker Interface: can determine something about an instances properties by using
  278. the provided convenience functions.
  279. """
  280. class DefinitionMarker:
  281. """marker for definitions
  282. """
  283. pass
  284. class DeclarationMarker:
  285. """marker for declarations
  286. """
  287. pass
  288. class AttributeMarker:
  289. """marker for attributes
  290. """
  291. pass
  292. class AttributeGroupMarker:
  293. """marker for attribute groups
  294. """
  295. pass
  296. class WildCardMarker:
  297. """marker for wildcards
  298. """
  299. pass
  300. class ElementMarker:
  301. """marker for wildcards
  302. """
  303. pass
  304. class ReferenceMarker:
  305. """marker for references
  306. """
  307. pass
  308. class ModelGroupMarker:
  309. """marker for model groups
  310. """
  311. pass
  312. class AllMarker(ModelGroupMarker):
  313. """marker for all model group
  314. """
  315. pass
  316. class ChoiceMarker(ModelGroupMarker):
  317. """marker for choice model group
  318. """
  319. pass
  320. class SequenceMarker(ModelGroupMarker):
  321. """marker for sequence model group
  322. """
  323. pass
  324. class ExtensionMarker:
  325. """marker for extensions
  326. """
  327. pass
  328. class RestrictionMarker:
  329. """marker for restrictions
  330. """
  331. facets = ['enumeration', 'length', 'maxExclusive', 'maxInclusive',\
  332. 'maxLength', 'minExclusive', 'minInclusive', 'minLength',\
  333. 'pattern', 'fractionDigits', 'totalDigits', 'whiteSpace']
  334. class SimpleMarker:
  335. """marker for simple type information
  336. """
  337. pass
  338. class ListMarker:
  339. """marker for simple type list
  340. """
  341. pass
  342. class UnionMarker:
  343. """marker for simple type Union
  344. """
  345. pass
  346. class ComplexMarker:
  347. """marker for complex type information
  348. """
  349. pass
  350. class LocalMarker:
  351. """marker for complex type information
  352. """
  353. pass
  354. class MarkerInterface:
  355. def isDefinition(self):
  356. return isinstance(self, DefinitionMarker)
  357. def isDeclaration(self):
  358. return isinstance(self, DeclarationMarker)
  359. def isAttribute(self):
  360. return isinstance(self, AttributeMarker)
  361. def isAttributeGroup(self):
  362. return isinstance(self, AttributeGroupMarker)
  363. def isElement(self):
  364. return isinstance(self, ElementMarker)
  365. def isReference(self):
  366. return isinstance(self, ReferenceMarker)
  367. def isWildCard(self):
  368. return isinstance(self, WildCardMarker)
  369. def isModelGroup(self):
  370. return isinstance(self, ModelGroupMarker)
  371. def isAll(self):
  372. return isinstance(self, AllMarker)
  373. def isChoice(self):
  374. return isinstance(self, ChoiceMarker)
  375. def isSequence(self):
  376. return isinstance(self, SequenceMarker)
  377. def isExtension(self):
  378. return isinstance(self, ExtensionMarker)
  379. def isRestriction(self):
  380. return isinstance(self, RestrictionMarker)
  381. def isSimple(self):
  382. return isinstance(self, SimpleMarker)
  383. def isComplex(self):
  384. return isinstance(self, ComplexMarker)
  385. def isLocal(self):
  386. return isinstance(self, LocalMarker)
  387. def isList(self):
  388. return isinstance(self, ListMarker)
  389. def isUnion(self):
  390. return isinstance(self, UnionMarker)
  391. ##########################################################
  392. # Schema Components
  393. #########################################################
  394. class XMLSchemaComponent(XMLBase, MarkerInterface):
  395. """
  396. class variables:
  397. required -- list of required attributes
  398. attributes -- dict of default attribute values, including None.
  399. Value can be a function for runtime dependencies.
  400. contents -- dict of namespace keyed content lists.
  401. 'xsd' content of xsd namespace.
  402. xmlns_key -- key for declared xmlns namespace.
  403. xmlns -- xmlns is special prefix for namespace dictionary
  404. xml -- special xml prefix for xml namespace.
  405. """
  406. required = []
  407. attributes = {}
  408. contents = {}
  409. xmlns_key = ''
  410. xmlns = 'xmlns'
  411. xml = 'xml'
  412. def __init__(self, parent=None):
  413. """parent -- parent instance
  414. instance variables:
  415. attributes -- dictionary of node's attributes
  416. """
  417. self.attributes = None
  418. self._parent = parent
  419. if self._parent:
  420. self._parent = weakref.ref(parent)
  421. if not self.__class__ == XMLSchemaComponent\
  422. and not (type(self.__class__.required) == type(XMLSchemaComponent.required)\
  423. and type(self.__class__.attributes) == type(XMLSchemaComponent.attributes)\
  424. and type(self.__class__.contents) == type(XMLSchemaComponent.contents)):
  425. raise RuntimeError('Bad type for a class variable in %s' % self.__class__)
  426. def getItemTrace(self):
  427. """Returns a node trace up to the <schema> item.
  428. """
  429. item, path, name, ref = self, [], 'name', 'ref'
  430. while not isinstance(item, XMLSchema) and not isinstance(item, WSDLToolsAdapter):
  431. attr = item.getAttribute(name)
  432. if not attr:
  433. attr = item.getAttribute(ref)
  434. if not attr:
  435. path.append('<%s>' % (item.tag))
  436. else:
  437. path.append('<%s ref="%s">' % (item.tag, attr))
  438. else:
  439. path.append('<%s name="%s">' % (item.tag, attr))
  440. item = item._parent()
  441. try:
  442. tns = item.getTargetNamespace()
  443. except:
  444. tns = ''
  445. path.append('<%s targetNamespace="%s">' % (item.tag, tns))
  446. path.reverse()
  447. return ''.join(path)
  448. def getTargetNamespace(self):
  449. """return targetNamespace
  450. """
  451. parent = self
  452. targetNamespace = 'targetNamespace'
  453. tns = self.attributes.get(targetNamespace)
  454. while not tns and parent and parent._parent is not None:
  455. parent = parent._parent()
  456. tns = parent.attributes.get(targetNamespace)
  457. return tns or ''
  458. def getAttributeDeclaration(self, attribute):
  459. """attribute -- attribute with a QName value (eg. type).
  460. collection -- check types collection in parent Schema instance
  461. """
  462. return self.getQNameAttribute(ATTRIBUTES, attribute)
  463. def getAttributeGroup(self, attribute):
  464. """attribute -- attribute with a QName value (eg. type).
  465. collection -- check types collection in parent Schema instance
  466. """
  467. return self.getQNameAttribute(ATTRIBUTE_GROUPS, attribute)
  468. def getTypeDefinition(self, attribute):
  469. """attribute -- attribute with a QName value (eg. type).
  470. collection -- check types collection in parent Schema instance
  471. """
  472. return self.getQNameAttribute(TYPES, attribute)
  473. def getElementDeclaration(self, attribute):
  474. """attribute -- attribute with a QName value (eg. element).
  475. collection -- check elements collection in parent Schema instance.
  476. """
  477. return self.getQNameAttribute(ELEMENTS, attribute)
  478. def getModelGroup(self, attribute):
  479. """attribute -- attribute with a QName value (eg. ref).
  480. collection -- check model_group collection in parent Schema instance.
  481. """
  482. return self.getQNameAttribute(MODEL_GROUPS, attribute)
  483. def getQNameAttribute(self, collection, attribute):
  484. """returns object instance representing QName --> (namespace,name),
  485. or if does not exist return None.
  486. attribute -- an information item attribute, with a QName value.
  487. collection -- collection in parent Schema instance to search.
  488. """
  489. tdc = self.getAttributeQName(attribute)
  490. if not tdc:
  491. return
  492. obj = self.getSchemaItem(collection, tdc.getTargetNamespace(), tdc.getName())
  493. if obj:
  494. return obj
  495. # raise SchemaError, 'No schema item "%s" in collection %s' %(tdc, collection)
  496. return
  497. def getSchemaItem(self, collection, namespace, name):
  498. """returns object instance representing namespace, name,
  499. or if does not exist return None if built-in, else
  500. raise SchemaError.
  501. namespace -- namespace item defined in.
  502. name -- name of item.
  503. collection -- collection in parent Schema instance to search.
  504. """
  505. parent = GetSchema(self)
  506. if parent.targetNamespace == namespace:
  507. try:
  508. obj = getattr(parent, collection)[name]
  509. except KeyError as ex:
  510. raise KeyError('targetNamespace(%s) collection(%s) has no item(%s)' % (namespace, collection, name))
  511. return obj
  512. if not namespace in parent.imports:
  513. if namespace in BUILT_IN_NAMESPACES:
  514. # built-in just return
  515. # WARNING: expecting import if "redefine" or add to built-in namespace.
  516. return
  517. raise SchemaError('schema "%s" does not import namespace "%s"' % (
  518. parent.targetNamespace, namespace))
  519. # Lazy Eval
  520. schema = parent.imports[namespace]
  521. if not isinstance(schema, XMLSchema):
  522. schema = schema.getSchema()
  523. if schema is not None:
  524. parent.imports[namespace] = schema
  525. if schema is None:
  526. if namespace in BUILT_IN_NAMESPACES:
  527. # built-in just return
  528. return
  529. raise SchemaError('no schema instance for imported namespace (%s).' % (namespace))
  530. if not isinstance(schema, XMLSchema):
  531. raise TypeError('expecting XMLSchema instance not "%r"' % schema)
  532. try:
  533. obj = getattr(schema, collection)[name]
  534. except KeyError as ex:
  535. raise KeyError('targetNamespace(%s) collection(%s) has no item(%s)' % (namespace, collection, name))
  536. return obj
  537. def getXMLNS(self, prefix=None):
  538. """deference prefix or by default xmlns, returns namespace.
  539. """
  540. if prefix == XMLSchemaComponent.xml:
  541. return XMLNS.XML
  542. parent = self
  543. ns = self.attributes[XMLSchemaComponent.xmlns].get(prefix or\
  544. XMLSchemaComponent.xmlns_key)
  545. while not ns:
  546. parent = parent._parent()
  547. ns = parent.attributes[XMLSchemaComponent.xmlns].get(prefix or\
  548. XMLSchemaComponent.xmlns_key)
  549. if not ns and isinstance(parent, WSDLToolsAdapter):
  550. if prefix is None:
  551. return ''
  552. raise SchemaError('unknown prefix %s' % prefix)
  553. return ns
  554. def getAttribute(self, attribute):
  555. """return requested attribute value or None
  556. """
  557. if type(attribute) in (list, tuple):
  558. if len(attribute) != 2:
  559. raise LookupError('To access attributes must use name or (namespace,name)')
  560. ns_dict = self.attributes.get(attribute[0])
  561. if ns_dict is None:
  562. return None
  563. return ns_dict.get(attribute[1])
  564. return self.attributes.get(attribute)
  565. def getAttributeQName(self, attribute):
  566. """return requested attribute value as (namespace,name) or None
  567. """
  568. qname = self.getAttribute(attribute)
  569. if isinstance(qname, TypeDescriptionComponent) is True:
  570. return qname
  571. if qname is None:
  572. return None
  573. prefix, ncname = SplitQName(qname)
  574. namespace = self.getXMLNS(prefix)
  575. return TypeDescriptionComponent((namespace, ncname))
  576. def getAttributeName(self):
  577. """return attribute name or None
  578. """
  579. return self.getAttribute('name')
  580. def setAttributes(self, node):
  581. """Sets up attribute dictionary, checks for required attributes and
  582. sets default attribute values. attr is for default attribute values
  583. determined at runtime.
  584. structure of attributes dictionary
  585. ['xmlns'][xmlns_key] -- xmlns namespace
  586. ['xmlns'][prefix] -- declared namespace prefix
  587. [namespace][prefix] -- attributes declared in a namespace
  588. [attribute] -- attributes w/o prefix, default namespaces do
  589. not directly apply to attributes, ie Name can't collide
  590. with QName.
  591. """
  592. self.attributes = {XMLSchemaComponent.xmlns: {}}
  593. for k, v in node.getAttributeDictionary().items():
  594. prefix, value = SplitQName(k)
  595. if value == XMLSchemaComponent.xmlns:
  596. self.attributes[value][prefix or XMLSchemaComponent.xmlns_key] = v
  597. elif prefix:
  598. ns = node.getNamespace(prefix)
  599. if not ns:
  600. raise SchemaError('no namespace for attribute prefix %s' % prefix)
  601. if not ns in self.attributes:
  602. self.attributes[ns] = {}
  603. elif value in self.attributes[ns]:
  604. raise SchemaError('attribute %s declared multiple times in %s' % (value, ns))
  605. self.attributes[ns][value] = v
  606. elif not value in self.attributes:
  607. self.attributes[value] = v
  608. else:
  609. raise SchemaError('attribute %s declared multiple times' % value)
  610. if not isinstance(self, WSDLToolsAdapter):
  611. self.__checkAttributes()
  612. self.__setAttributeDefaults()
  613. #set QNames
  614. for k in ['type', 'element', 'base', 'ref', 'substitutionGroup', 'itemType']:
  615. if k in self.attributes:
  616. prefix, value = SplitQName(self.attributes.get(k))
  617. self.attributes[k] = \
  618. TypeDescriptionComponent((self.getXMLNS(prefix), value))
  619. #Union, memberTypes is a whitespace separated list of QNames
  620. for k in ['memberTypes']:
  621. if k in self.attributes:
  622. qnames = self.attributes[k]
  623. self.attributes[k] = []
  624. for qname in qnames.split():
  625. prefix, value = SplitQName(qname)
  626. self.attributes['memberTypes'].append(\
  627. TypeDescriptionComponent(\
  628. (self.getXMLNS(prefix), value)))
  629. def getContents(self, node):
  630. """retrieve xsd contents
  631. """
  632. return node.getContentList(*self.__class__.contents['xsd'])
  633. def __setAttributeDefaults(self):
  634. """Looks for default values for unset attributes. If
  635. class variable representing attribute is None, then
  636. it must be defined as an instance variable.
  637. """
  638. for k, v in self.__class__.attributes.items():
  639. if v is not None and k in self.attributes is False:
  640. if isinstance(v, types.FunctionType):
  641. self.attributes[k] = v(self)
  642. else:
  643. self.attributes[k] = v
  644. def __checkAttributes(self):
  645. """Checks that required attributes have been defined,
  646. attributes w/default cannot be required. Checks
  647. all defined attributes are legal, attribute
  648. references are not subject to this test.
  649. """
  650. for a in self.__class__.required:
  651. if not a in self.attributes:
  652. raise SchemaError('class instance %s, missing required attribute %s' % (self.__class__, a))
  653. for a, v in self.attributes.items():
  654. # attribute #other, ie. not in empty namespace
  655. if type(v) is dict:
  656. continue
  657. # predefined prefixes xmlns, xml
  658. if a in (XMLSchemaComponent.xmlns, XMLNS.XML):
  659. continue
  660. if (a not in self.__class__.attributes.keys()) and not\
  661. (self.isAttribute() and self.isReference()):
  662. raise SchemaError('%s, unknown attribute(%s, %s)' % (self.getItemTrace(), a, self.attributes[a]))
  663. class WSDLToolsAdapter(XMLSchemaComponent):
  664. """WSDL Adapter to grab the attributes from the wsdl document node.
  665. """
  666. attributes = {'name': None, 'targetNamespace': None}
  667. tag = 'definitions'
  668. def __init__(self, wsdl):
  669. XMLSchemaComponent.__init__(self, parent=wsdl)
  670. self.setAttributes(DOMAdapter(wsdl.document))
  671. def getImportSchemas(self):
  672. """returns WSDLTools.WSDL types Collection
  673. """
  674. return self._parent().types
  675. class Notation(XMLSchemaComponent):
  676. """<notation>
  677. parent:
  678. schema
  679. attributes:
  680. id -- ID
  681. name -- NCName, Required
  682. public -- token, Required
  683. system -- anyURI
  684. contents:
  685. annotation?
  686. """
  687. required = ['name', 'public']
  688. attributes = {'id': None, 'name': None, 'public': None, 'system': None}
  689. contents = {'xsd': ('annotation')}
  690. tag = 'notation'
  691. def __init__(self, parent):
  692. XMLSchemaComponent.__init__(self, parent)
  693. self.annotation = None
  694. def fromDom(self, node):
  695. self.setAttributes(node)
  696. contents = self.getContents(node)
  697. for i in contents:
  698. component = SplitQName(i.getTagName())[1]
  699. if component == 'annotation' and not self.annotation:
  700. self.annotation = Annotation(self)
  701. self.annotation.fromDom(i)
  702. else:
  703. raise SchemaError('Unknown component (%s)' % (i.getTagName()))
  704. class Annotation(XMLSchemaComponent):
  705. """<annotation>
  706. parent:
  707. all,any,anyAttribute,attribute,attributeGroup,choice,complexContent,
  708. complexType,element,extension,field,group,import,include,key,keyref,
  709. list,notation,redefine,restriction,schema,selector,simpleContent,
  710. simpleType,union,unique
  711. attributes:
  712. id -- ID
  713. contents:
  714. (documentation | appinfo)*
  715. """
  716. attributes = {'id': None}
  717. contents = {'xsd': ('documentation', 'appinfo')}
  718. tag = 'annotation'
  719. def __init__(self, parent):
  720. XMLSchemaComponent.__init__(self, parent)
  721. self.content = None
  722. def fromDom(self, node):
  723. self.setAttributes(node)
  724. contents = self.getContents(node)
  725. content = []
  726. for i in contents:
  727. component = SplitQName(i.getTagName())[1]
  728. if component == 'documentation':
  729. #print_debug('class %s, documentation skipped' %self.__class__, 5)
  730. continue
  731. elif component == 'appinfo':
  732. #print_debug('class %s, appinfo skipped' %self.__class__, 5)
  733. continue
  734. else:
  735. raise SchemaError('Unknown component (%s)' % (i.getTagName()))
  736. self.content = tuple(content)
  737. class Documentation(XMLSchemaComponent):
  738. """<documentation>
  739. parent:
  740. annotation
  741. attributes:
  742. source, anyURI
  743. xml:lang, language
  744. contents:
  745. mixed, any
  746. """
  747. attributes = {'source': None, 'xml: lang': None}
  748. contents = {'xsd': ('mixed', 'any')}
  749. tag = 'documentation'
  750. def __init__(self, parent):
  751. XMLSchemaComponent.__init__(self, parent)
  752. self.content = None
  753. def fromDom(self, node):
  754. self.setAttributes(node)
  755. contents = self.getContents(node)
  756. content = []
  757. for i in contents:
  758. component = SplitQName(i.getTagName())[1]
  759. if component == 'mixed':
  760. #print_debug('class %s, mixed skipped' %self.__class__, 5)
  761. continue
  762. elif component == 'any':
  763. #print_debug('class %s, any skipped' %self.__class__, 5)
  764. continue
  765. else:
  766. raise SchemaError('Unknown component (%s)' % (i.getTagName()))
  767. self.content = tuple(content)
  768. class Appinfo(XMLSchemaComponent):
  769. """<appinfo>
  770. parent:
  771. annotation
  772. attributes:
  773. source, anyURI
  774. contents:
  775. mixed, any
  776. """
  777. attributes = {'source': None, 'anyURI': None}
  778. contents = {'xsd': ('mixed', 'any')}
  779. tag = 'appinfo'
  780. def __init__(self, parent):
  781. XMLSchemaComponent.__init__(self, parent)
  782. self.content = None
  783. def fromDom(self, node):
  784. self.setAttributes(node)
  785. contents = self.getContents(node)
  786. content = []
  787. for i in contents:
  788. component = SplitQName(i.getTagName())[1]
  789. if component == 'mixed':
  790. #print_debug('class %s, mixed skipped' %self.__class__, 5)
  791. continue
  792. elif component == 'any':
  793. #print_debug('class %s, any skipped' %self.__class__, 5)
  794. continue
  795. else:
  796. raise SchemaError('Unknown component (%s)' % (i.getTagName()))
  797. self.content = tuple(content)
  798. class XMLSchemaFake:
  799. # This is temporary, for the benefit of WSDL until the real thing works.
  800. def __init__(self, element):
  801. self.targetNamespace = DOM.getAttr(element, 'targetNamespace')
  802. self.element = element
  803. class XMLSchema(XMLSchemaComponent):
  804. """A schema is a collection of schema components derived from one
  805. or more schema documents, that is, one or more <schema> element
  806. information items. It represents the abstract notion of a schema
  807. rather than a single schema document (or other representation).
  808. <schema>
  809. parent:
  810. ROOT
  811. attributes:
  812. id -- ID
  813. version -- token
  814. xml:lang -- language
  815. targetNamespace -- anyURI
  816. attributeFormDefault -- 'qualified' | 'unqualified', 'unqualified'
  817. elementFormDefault -- 'qualified' | 'unqualified', 'unqualified'
  818. blockDefault -- '#all' | list of
  819. ('substitution | 'extension' | 'restriction')
  820. finalDefault -- '#all' | list of
  821. ('extension' | 'restriction' | 'list' | 'union')
  822. contents:
  823. ((include | import | redefine | annotation)*,
  824. (attribute, attributeGroup, complexType, element, group,
  825. notation, simpleType)*, annotation*)*
  826. attributes -- schema attributes
  827. imports -- import statements
  828. includes -- include statements
  829. redefines --
  830. types -- global simpleType, complexType definitions
  831. elements -- global element declarations
  832. attr_decl -- global attribute declarations
  833. attr_groups -- attribute Groups
  834. model_groups -- model Groups
  835. notations -- global notations
  836. """
  837. attributes = {'id': None,
  838. 'version': None,
  839. 'xml: lang': None,
  840. 'targetNamespace': None,
  841. 'attributeFormDefault': 'unqualified',
  842. 'elementFormDefault': 'unqualified',
  843. 'blockDefault': None,
  844. 'finalDefault': None}
  845. contents = {'xsd': ('include', 'import', 'redefine', 'annotation',
  846. 'attribute', 'attributeGroup', 'complexType',
  847. 'element', 'group', 'notation', 'simpleType',
  848. 'annotation')}
  849. empty_namespace = ''
  850. tag = 'schema'
  851. def __init__(self, parent=None, logger=None):
  852. """parent --
  853. instance variables:
  854. targetNamespace -- schema's declared targetNamespace, or empty string.
  855. _imported_schemas -- namespace keyed dict of schema dependencies, if
  856. a schema is provided instance will not resolve import statement.
  857. _included_schemas -- schemaLocation keyed dict of component schemas,
  858. if schema is provided instance will not resolve include statement.
  859. _base_url -- needed for relative URLs support, only works with URLs
  860. relative to initial document.
  861. includes -- collection of include statements
  862. imports -- collection of import statements
  863. elements -- collection of global element declarations
  864. types -- collection of global type definitions
  865. attr_decl -- collection of global attribute declarations
  866. attr_groups -- collection of global attribute group definitions
  867. model_groups -- collection of model group definitions
  868. notations -- collection of notations
  869. """
  870. self.__node = None
  871. self.targetNamespace = None
  872. XMLSchemaComponent.__init__(self, parent)
  873. f = lambda k: k.attributes['name']
  874. ns = lambda k: k.attributes['namespace']
  875. sl = lambda k: k.attributes['schemaLocation']
  876. self.includes = Collection(self, key=sl)
  877. self.imports = Collection(self, key=ns)
  878. self.elements = Collection(self, key=f)
  879. self.types = Collection(self, key=f)
  880. self.attr_decl = Collection(self, key=f)
  881. self.attr_groups = Collection(self, key=f)
  882. self.model_groups = Collection(self, key=f)
  883. self.notations = Collection(self, key=f)
  884. self._imported_schemas = {}
  885. self._included_schemas = {}
  886. self._base_url = None
  887. self.logger = logger or logging.getLogger(__name__)
  888. def getNode(self):
  889. """
  890. Interacting with the underlying DOM tree.
  891. """
  892. return self.__node
  893. def addImportSchema(self, schema):
  894. """for resolving import statements in Schema instance
  895. schema -- schema instance
  896. _imported_schemas
  897. """
  898. if not isinstance(schema, XMLSchema):
  899. raise TypeError('expecting a Schema instance')
  900. if schema.targetNamespace != self.targetNamespace:
  901. self._imported_schemas[schema.targetNamespace] = schema
  902. else:
  903. raise SchemaError('import schema bad targetNamespace')
  904. def addIncludeSchema(self, schemaLocation, schema):
  905. """for resolving include statements in Schema instance
  906. schemaLocation -- schema location
  907. schema -- schema instance
  908. _included_schemas
  909. """
  910. if not isinstance(schema, XMLSchema):
  911. raise TypeError('expecting a Schema instance')
  912. if not schema.targetNamespace or\
  913. schema.targetNamespace == self.targetNamespace:
  914. self._included_schemas[schemaLocation] = schema
  915. else:
  916. raise SchemaError('include schema bad targetNamespace')
  917. def setImportSchemas(self, schema_dict):
  918. """set the import schema dictionary, which is used to
  919. reference depedent schemas.
  920. """
  921. self._imported_schemas = schema_dict
  922. def getImportSchemas(self):
  923. """get the import schema dictionary, which is used to
  924. reference depedent schemas.
  925. """
  926. return self._imported_schemas
  927. def getSchemaNamespacesToImport(self):
  928. """returns tuple of namespaces the schema instance has declared
  929. itself to be depedent upon.
  930. """
  931. return tuple(self.includes.keys())
  932. def setIncludeSchemas(self, schema_dict):
  933. """set the include schema dictionary, which is keyed with
  934. schemaLocation (uri).
  935. This is a means of providing
  936. schemas to the current schema for content inclusion.
  937. """
  938. self._included_schemas = schema_dict
  939. def getIncludeSchemas(self):
  940. """get the include schema dictionary, which is keyed with
  941. schemaLocation (uri).
  942. """
  943. return self._included_schemas
  944. def getBaseUrl(self):
  945. """get base url, used for normalizing all relative uri's
  946. """
  947. return self._base_url
  948. def setBaseUrl(self, url):
  949. """set base url, used for normalizing all relative uri's
  950. """
  951. self._base_url = url
  952. def getElementFormDefault(self):
  953. """return elementFormDefault attribute
  954. """
  955. return self.attributes.get('elementFormDefault')
  956. def isElementFormDefaultQualified(self):
  957. return self.attributes.get('elementFormDefault') == 'qualified'
  958. def getAttributeFormDefault(self):
  959. """return attributeFormDefault attribute
  960. """
  961. return self.attributes.get('attributeFormDefault')
  962. def getBlockDefault(self):
  963. """return blockDefault attribute
  964. """
  965. return self.attributes.get('blockDefault')
  966. def getFinalDefault(self):
  967. """return finalDefault attribute
  968. """
  969. return self.attributes.get('finalDefault')
  970. def load(self, node, location=None):
  971. self.__node = node
  972. pnode = node.getParentNode()
  973. if pnode:
  974. pname = SplitQName(pnode.getTagName())[1]
  975. if pname == 'types':
  976. attributes = {}
  977. self.setAttributes(pnode)
  978. attributes.update(self.attributes)
  979. self.setAttributes(node)
  980. for k, v in attributes['xmlns'].items():
  981. if not k in self.attributes['xmlns']:
  982. self.attributes['xmlns'][k] = v
  983. else:
  984. self.setAttributes(node)
  985. else:
  986. self.setAttributes(node)
  987. self.targetNamespace = self.getTargetNamespace()
  988. for childNode in self.getContents(node):
  989. component = SplitQName(childNode.getTagName())[1]
  990. if component == 'include':
  991. tp = self.__class__.Include(self)
  992. tp.fromDom(childNode)
  993. sl = tp.attributes['schemaLocation']
  994. schema = tp.getSchema()
  995. if sl not in self.getIncludeSchemas():
  996. self.addIncludeSchema(sl, schema)
  997. self.includes[sl] = tp
  998. pn = childNode.getParentNode().getNode()
  999. pn.removeChild(childNode.getNode())
  1000. for child in schema.getNode().getNode().childNodes:
  1001. pn.appendChild(child.cloneNode(1))
  1002. for collection in ['imports', 'elements', 'types',
  1003. 'attr_decl', 'attr_groups', 'model_groups',
  1004. 'notations']:
  1005. for k, v in getattr(schema, collection).items():
  1006. if k not in getattr(self, collection):
  1007. v._parent = weakref.ref(self)
  1008. getattr(self, collection)[k] = v
  1009. else:
  1010. warnings.warn("Not keeping schema component.")
  1011. elif component == 'import':
  1012. slocd = SchemaReader.namespaceToSchema
  1013. tp = self.__class__.Import(self)
  1014. tp.fromDom(childNode)
  1015. import_ns = tp.getAttribute('namespace') or\
  1016. self.__class__.empty_namespace
  1017. schema = slocd.get(import_ns)
  1018. if schema is None:
  1019. schema = XMLSchema()
  1020. slocd[import_ns] = schema
  1021. try:
  1022. tp.loadSchema(schema)
  1023. except NoSchemaLocationWarning as ex:
  1024. # Dependency declaration, hopefully implementation
  1025. # is aware of this namespace (eg. SOAP,WSDL,?)
  1026. self.logger.debug("IMPORT: %s : %s" % (import_ns, ex))
  1027. del slocd[import_ns]
  1028. continue
  1029. except SchemaError as ex:
  1030. #warnings.warn(\
  1031. # '<import namespace="%s" schemaLocation=?>, %s'\
  1032. # %(import_ns, 'failed to load schema instance')
  1033. #)
  1034. self.logger.debug(ex)
  1035. del slocd[import_ns]
  1036. class _LazyEvalImport(str):
  1037. '''Lazy evaluation of import, replace entry in self.imports.'''
  1038. #attributes = dict(namespace=import_ns)
  1039. def getSchema(namespace):
  1040. schema = slocd.get(namespace)
  1041. if schema is None:
  1042. parent = self._parent()
  1043. wstypes = parent
  1044. if isinstance(parent, WSDLToolsAdapter):
  1045. wstypes = parent.getImportSchemas()
  1046. schema = wstypes.get(namespace)
  1047. if isinstance(schema, XMLSchema):
  1048. self.imports[namespace] = schema
  1049. return schema
  1050. return None
  1051. self.imports[import_ns] = _LazyEvalImport(import_ns)
  1052. continue
  1053. else:
  1054. tp._schema = schema
  1055. if import_ns in self.getImportSchemas():
  1056. warnings.warn(\
  1057. 'Detected multiple imports of the namespace "%s" '\
  1058. % import_ns)
  1059. self.addImportSchema(schema)
  1060. # spec says can have multiple imports of same namespace
  1061. # but purpose of import is just dependency declaration.
  1062. self.imports[import_ns] = tp
  1063. elif component == 'redefine':
  1064. warnings.warn('redefine is ignored')
  1065. elif component == 'annotation':
  1066. warnings.warn('annotation is ignored')
  1067. elif component == 'attribute':
  1068. tp = AttributeDeclaration(self)
  1069. tp.fromDom(childNode)
  1070. self.attr_decl[tp.getAttribute('name')] = tp
  1071. elif component == 'attributeGroup':
  1072. tp = AttributeGroupDefinition(self)
  1073. tp.fromDom(childNode)
  1074. self.attr_groups[tp.getAttribute('name')] = tp
  1075. elif component == 'element':
  1076. tp = ElementDeclaration(self)
  1077. tp.fromDom(childNode)
  1078. self.elements[tp.getAttribute('name')] = tp
  1079. elif component == 'group':
  1080. tp = ModelGroupDefinition(self)
  1081. tp.fromDom(childNode)
  1082. self.model_groups[tp.getAttribute('name')] = tp
  1083. elif component == 'notation':
  1084. tp = Notation(self)
  1085. tp.fromDom(childNode)
  1086. self.notations[tp.getAttribute('name')] = tp
  1087. elif component == 'complexType':
  1088. tp = ComplexType(self)
  1089. tp.fromDom(childNode)
  1090. self.types[tp.getAttribute('name')] = tp
  1091. elif component == 'simpleType':
  1092. tp = SimpleType(self)
  1093. tp.fromDom(childNode)
  1094. self.types[tp.getAttribute('name')] = tp
  1095. else:
  1096. break
  1097. class Import(XMLSchemaComponent):
  1098. """<import>
  1099. parent:
  1100. schema
  1101. attributes:
  1102. id -- ID
  1103. namespace -- anyURI
  1104. schemaLocation -- anyURI
  1105. contents:
  1106. annotation?
  1107. """
  1108. attributes = {'id': None,
  1109. 'namespace': None,
  1110. 'schemaLocation': None}
  1111. contents = {'xsd': ['annotation']}
  1112. tag = 'import'
  1113. def __init__(self, parent):
  1114. XMLSchemaComponent.__init__(self, parent)
  1115. self.annotation = None
  1116. self._schema = None
  1117. def fromDom(self, node):
  1118. self.setAttributes(node)
  1119. contents = self.getContents(node)
  1120. if self.attributes['namespace'] == self.getTargetNamespace():
  1121. raise SchemaError('namespace of schema and import match')
  1122. for i in contents:
  1123. component = SplitQName(i.getTagName())[1]
  1124. if component == 'annotation' and not self.annotation:
  1125. self.annotation = Annotation(self)
  1126. self.annotation.fromDom(i)
  1127. else:
  1128. raise SchemaError('Unknown component (%s)' % (i.getTagName()))
  1129. def getSchema(self):
  1130. """if schema is not defined, first look for a Schema class instance
  1131. in parent Schema. Else if not defined resolve schemaLocation
  1132. and create a new Schema class instance, and keep a hard reference.
  1133. """
  1134. if not self._schema:
  1135. ns = self.attributes['namespace']
  1136. schema = self._parent().getImportSchemas().get(ns)
  1137. if not schema and self._parent()._parent:
  1138. schema = self._parent()._parent().getImportSchemas().get(ns)
  1139. if not schema:
  1140. url = self.attributes.get('schemaLocation')
  1141. if not url:
  1142. raise SchemaError('namespace(%s) is unknown' % ns)
  1143. base_url = self._parent().getBaseUrl()
  1144. reader = SchemaReader(base_url=base_url)
  1145. reader._imports = self._parent().getImportSchemas()
  1146. reader._includes = self._parent().getIncludeSchemas()
  1147. self._schema = reader.loadFromURL(url)
  1148. return self._schema or schema
  1149. def loadSchema(self, schema):
  1150. """
  1151. """
  1152. base_url = self._parent().getBaseUrl()
  1153. reader = SchemaReader(base_url=base_url)
  1154. reader._imports = self._parent().getImportSchemas()
  1155. reader._includes = self._parent().getIncludeSchemas()
  1156. self._schema = schema
  1157. if not 'schemaLocation' in self.attributes:
  1158. raise NoSchemaLocationWarning('no schemaLocation attribute in import')
  1159. reader.loadFromURL(self.attributes.get('schemaLocation'), schema)
  1160. class Include(XMLSchemaComponent):
  1161. """<include schemaLocation>
  1162. parent:
  1163. schema
  1164. attributes:
  1165. id -- ID
  1166. schemaLocation -- anyURI, required
  1167. contents:
  1168. annotation?
  1169. """
  1170. required = ['schemaLocation']
  1171. attributes = {'id': None,
  1172. 'schemaLocation': None}
  1173. contents = {'xsd': ['annotation']}
  1174. tag = 'include'
  1175. def __init__(self, parent):
  1176. XMLSchemaComponent.__init__(self, parent)
  1177. self.annotation = None
  1178. self._schema = None
  1179. def fromDom(self, node):
  1180. self.setAttributes(node)
  1181. contents = self.getContents(node)
  1182. for i in contents:
  1183. component = SplitQName(i.getTagName())[1]
  1184. if component == 'annotation' and not self.annotation:
  1185. self.annotation = Annotation(self)
  1186. self.annotation.fromDom(i)
  1187. else:
  1188. raise SchemaError('Unknown component (%s)' % (i.getTagName()))
  1189. def getSchema(self):
  1190. """if schema is not defined, first look for a Schema class instance
  1191. in parent Schema. Else if not defined resolve schemaLocation
  1192. and create a new Schema class instance.
  1193. """
  1194. if not self._schema:
  1195. schema = self._parent()
  1196. self._schema = schema.getIncludeSchemas().get(self.attributes['schemaLocation'])
  1197. if not self._schema:
  1198. url = self.attributes['schemaLocation']
  1199. reader = SchemaReader(base_url=schema.getBaseUrl())
  1200. reader._imports = schema.getImportSchemas()
  1201. reader._includes = schema.getIncludeSchemas()
  1202. # create schema before loading so chameleon include
  1203. # will evalute targetNamespace correctly.
  1204. self._schema = XMLSchema(schema)
  1205. reader.loadFromURL(url, self._schema)
  1206. return self._schema
  1207. class AttributeDeclaration(XMLSchemaComponent,\
  1208. AttributeMarker,\
  1209. DeclarationMarker):
  1210. """<attribute name>
  1211. parent:
  1212. schema
  1213. attributes:
  1214. id -- ID
  1215. name -- NCName, required
  1216. type -- QName
  1217. default -- string
  1218. fixed -- string
  1219. contents:
  1220. annotation?, simpleType?
  1221. """
  1222. required = ['name']
  1223. attributes = {'id': None,
  1224. 'name': None,
  1225. 'type': None,
  1226. 'default': None,
  1227. 'fixed': None}
  1228. contents = {'xsd': ['annotation', 'simpleType']}
  1229. tag = 'attribute'
  1230. def __init__(self, parent):
  1231. XMLSchemaComponent.__init__(self, parent)
  1232. self.annotation = None
  1233. self.content = None
  1234. def fromDom(self, node):
  1235. """ No list or union support
  1236. """
  1237. self.setAttributes(node)
  1238. contents = self.getContents(node)
  1239. for i in contents:
  1240. component = SplitQName(i.getTagName())[1]
  1241. if component == 'annotation' and not self.annotation:
  1242. self.annotation = Annotation(self)
  1243. self.annotation.fromDom(i)
  1244. elif component == 'simpleType':
  1245. self.content = AnonymousSimpleType(self)
  1246. self.content.fromDom(i)
  1247. else:
  1248. raise SchemaError('Unknown component (%s)' % (i.getTagName()))
  1249. class LocalAttributeDeclaration(AttributeDeclaration,\
  1250. AttributeMarker,\
  1251. LocalMarker,\
  1252. DeclarationMarker):
  1253. """<attribute name>
  1254. parent:
  1255. complexType, restriction, extension, attributeGroup
  1256. attributes:
  1257. id -- ID
  1258. name -- NCName, required
  1259. type -- QName
  1260. form -- ('qualified' | 'unqualified'), schema.attributeFormDefault
  1261. use -- ('optional' | 'prohibited' | 'required'), optional
  1262. default -- string
  1263. fixed -- string
  1264. contents:
  1265. annotation?, simpleType?
  1266. """
  1267. required = ['name']
  1268. attributes = {'id': None,
  1269. 'name': None,
  1270. 'type': None,
  1271. 'form': lambda self: GetSchema(self).getAttributeFormDefault(),
  1272. 'use': 'optional',
  1273. 'default': None,
  1274. 'fixed': None}
  1275. contents = {'xsd': ['annotation', 'simpleType']}
  1276. def __init__(self, parent):
  1277. AttributeDeclaration.__init__(self, parent)
  1278. self.annotation = None
  1279. self.content = None
  1280. def fromDom(self, node):
  1281. self.setAttributes(node)
  1282. contents = self.getContents(node)
  1283. for i in contents:
  1284. component = SplitQName(i.getTagName())[1]
  1285. if component == 'annotation' and not self.annotation:
  1286. self.annotation = Annotation(self)
  1287. self.annotation.fromDom(i)
  1288. elif component == 'simpleType':
  1289. self.content = AnonymousSimpleType(self)
  1290. self.content.fromDom(i)
  1291. else:
  1292. raise SchemaError('Unknown component (%s)' % (i.getTagName()))
  1293. class AttributeWildCard(XMLSchemaComponent,\
  1294. AttributeMarker,\
  1295. DeclarationMarker,\
  1296. WildCardMarker):
  1297. """<anyAttribute>
  1298. parents:
  1299. complexType, restriction, extension, attributeGroup
  1300. attributes:
  1301. id -- ID
  1302. namespace -- '##any' | '##other' |
  1303. (anyURI* | '##targetNamespace' | '##local'), ##any
  1304. processContents -- 'lax' | 'skip' | 'strict', strict
  1305. contents:
  1306. annotation?
  1307. """
  1308. attributes = {'id': None,
  1309. 'namespace': '##any',
  1310. 'processContents': 'strict'}
  1311. contents = {'xsd': ['annotation']}
  1312. tag = 'anyAttribute'
  1313. def __init__(self, parent):
  1314. XMLSchemaComponent.__init__(self, parent)
  1315. self.annotation = None
  1316. def fromDom(self, node):
  1317. self.setAttributes(node)
  1318. contents = self.getContents(node)
  1319. for i in contents:
  1320. component = SplitQName(i.getTagName())[1]
  1321. if component == 'annotation' and not self.annotation:
  1322. self.annotation = Annotation(self)
  1323. self.annotation.fromDom(i)
  1324. else:
  1325. raise SchemaError('Unknown component (%s)' % (i.getTagName()))
  1326. class AttributeReference(XMLSchemaComponent,\
  1327. AttributeMarker,\
  1328. ReferenceMarker):
  1329. """<attribute ref>
  1330. parents:
  1331. complexType, restriction, extension, attributeGroup
  1332. attributes:
  1333. id -- ID
  1334. ref -- QName, required
  1335. use -- ('optional' | 'prohibited' | 'required'), optional
  1336. default -- string
  1337. fixed -- string
  1338. contents:
  1339. annotation?
  1340. """
  1341. required = ['ref']
  1342. attributes = {'id': None,
  1343. 'ref': None,
  1344. 'use': 'optional',
  1345. 'default': None,
  1346. 'fixed': None}
  1347. contents = {'xsd': ['annotation']}
  1348. tag = 'attribute'
  1349. def __init__(self, parent):
  1350. XMLSchemaComponent.__init__(self, parent)
  1351. self.annotation = None
  1352. def getAttributeDeclaration(self, attribute='ref'):
  1353. return XMLSchemaComponent.getAttributeDeclaration(self, attribute)
  1354. def fromDom(self, node):
  1355. self.setAttributes(node)
  1356. contents = self.getContents(node)
  1357. for i in contents:
  1358. component = SplitQName(i.getTagName())[1]
  1359. if component == 'annotation' and not self.annotation:
  1360. self.annotation = Annotation(self)
  1361. self.annotation.fromDom(i)
  1362. else:
  1363. raise SchemaError('Unknown component (%s)' % (i.getTagName()))
  1364. class AttributeGroupDefinition(XMLSchemaComponent,\
  1365. AttributeGroupMarker,\
  1366. DefinitionMarker):
  1367. """<attributeGroup name>
  1368. parents:
  1369. schema, redefine
  1370. attributes:
  1371. id -- ID
  1372. name -- NCName, required
  1373. contents:
  1374. annotation?, (attribute | attributeGroup)*, anyAttribute?
  1375. """
  1376. required = ['name']
  1377. attributes = {'id': None,
  1378. 'name': None}
  1379. contents = {'xsd': ['annotation', 'attribute', 'attributeGroup', 'anyAttribute']}
  1380. tag = 'attributeGroup'
  1381. def __init__(self, parent):
  1382. XMLSchemaComponent.__init__(self, parent)
  1383. self.annotation = None
  1384. self.attr_content = None
  1385. def getAttributeContent(self):
  1386. return self.attr_content
  1387. def fromDom(self, node):
  1388. self.setAttributes(node)
  1389. contents = self.getContents(node)
  1390. content = []
  1391. for indx in range(len(contents)):
  1392. component = SplitQName(contents[indx].getTagName())[1]
  1393. if (component == 'annotation') and (not indx):
  1394. self.annotation = Annotation(self)
  1395. self.annotation.fromDom(contents[indx])
  1396. elif component == 'attribute':
  1397. if contents[indx].hasattr('name'):
  1398. content.append(LocalAttributeDeclaration(self))
  1399. elif contents[indx].hasattr('ref'):
  1400. content.append(AttributeReference(self))
  1401. else:
  1402. raise SchemaError('Unknown attribute type')
  1403. content[-1].fromDom(contents[indx])
  1404. elif component == 'attributeGroup':
  1405. content.append(AttributeGroupReference(self))
  1406. content[-1].fromDom(contents[indx])
  1407. elif component == 'anyAttribute':
  1408. if len(contents) != indx + 1:
  1409. raise SchemaError('anyAttribute is out of order in %s' % self.getItemTrace())
  1410. content.append(AttributeWildCard(self))
  1411. content[-1].fromDom(contents[indx])
  1412. else:
  1413. raise SchemaError('Unknown component (%s)' % (contents[indx].getTagName()))
  1414. self.attr_content = tuple(content)
  1415. class AttributeGroupReference(XMLSchemaComponent,\
  1416. AttributeGroupMarker,\
  1417. ReferenceMarker):
  1418. """<attributeGroup ref>
  1419. parents:
  1420. complexType, restriction, extension, attributeGroup
  1421. attributes:
  1422. id -- ID
  1423. ref -- QName, required
  1424. contents:
  1425. annotation?
  1426. """
  1427. required = ['ref']
  1428. attributes = {'id': None,
  1429. 'ref': None}
  1430. contents = {'xsd': ['annotation']}
  1431. tag = 'attributeGroup'
  1432. def __init__(self, parent):
  1433. XMLSchemaComponent.__init__(self, parent)
  1434. self.annotation = None
  1435. def getAttributeGroup(self, attribute='ref'):
  1436. """attribute -- attribute with a QName value (eg. type).
  1437. collection -- check types collection in parent Schema instance
  1438. """
  1439. return XMLSchemaComponent.getAttributeGroup(self, attribute)
  1440. def fromDom(self, node):
  1441. self.setAttributes(node)
  1442. contents = self.getContents(node)
  1443. for i in contents:
  1444. component = SplitQName(i.getTagName())[1]
  1445. if component == 'annotation' and not self.annotation:
  1446. self.annotation = Annotation(self)
  1447. self.annotation.fromDom(i)
  1448. else:
  1449. raise SchemaError('Unknown component (%s)' % (i.getTagName()))
  1450. ######################################################
  1451. # Elements
  1452. #####################################################
  1453. class IdentityConstrants(XMLSchemaComponent):
  1454. """Allow one to uniquely identify nodes in a document and ensure the
  1455. integrity of references between them.
  1456. attributes -- dictionary of attributes
  1457. selector -- XPath to selected nodes
  1458. fields -- list of XPath to key field
  1459. """
  1460. def __init__(self, parent):
  1461. XMLSchemaComponent.__init__(self, parent)
  1462. self.selector = None
  1463. self.fields = None
  1464. self.annotation = None
  1465. def fromDom(self, node):
  1466. self.setAttributes(node)
  1467. contents = self.getContents(node)
  1468. fields = []
  1469. for i in contents:
  1470. component = SplitQName(i.getTagName())[1]
  1471. if component in self.__class__.contents['xsd']:
  1472. if component == 'annotation' and not self.annotation:
  1473. self.annotation = Annotation(self)
  1474. self.annotation.fromDom(i)
  1475. elif component == 'selector':
  1476. self.selector = self.Selector(self)
  1477. self.selector.fromDom(i)
  1478. continue
  1479. elif component == 'field':
  1480. fields.append(self.Field(self))
  1481. fields[-1].fromDom(i)
  1482. continue
  1483. else:
  1484. raise SchemaError('Unknown component (%s)' % (i.getTagName()))
  1485. else:
  1486. raise SchemaError('Unknown component (%s)' % (i.getTagName()))
  1487. self.fields = tuple(fields)
  1488. class Constraint(XMLSchemaComponent):
  1489. def __init__(self, parent):
  1490. XMLSchemaComponent.__init__(self, parent)
  1491. self.annotation = None
  1492. def fromDom(self, node):
  1493. self.setAttributes(node)
  1494. contents = self.getContents(node)
  1495. for i in contents:
  1496. component = SplitQName(i.getTagName())[1]
  1497. if component in self.__class__.contents['xsd']:
  1498. if component == 'annotation' and not self.annotation:
  1499. self.annotation = Annotation(self)
  1500. self.annotation.fromDom(i)
  1501. else:
  1502. raise SchemaError('Unknown component (%s)' % (i.getTagName()))
  1503. else:
  1504. raise SchemaError('Unknown component (%s)' % (i.getTagName()))
  1505. class Selector(Constraint):
  1506. """<selector xpath>
  1507. parent:
  1508. unique, key, keyref
  1509. attributes:
  1510. id -- ID
  1511. xpath -- XPath subset, required
  1512. contents:
  1513. annotation?
  1514. """
  1515. required = ['xpath']
  1516. attributes = {'id': None,
  1517. 'xpath': None}
  1518. contents = {'xsd': ['annotation']}
  1519. tag = 'selector'
  1520. class Field(Constraint):
  1521. """<field xpath>
  1522. parent:
  1523. unique, key, keyref
  1524. attributes:
  1525. id -- ID
  1526. xpath -- XPath subset, required
  1527. contents:
  1528. annotation?
  1529. """
  1530. required = ['xpath']
  1531. attributes = {'id': None,
  1532. 'xpath': None}
  1533. contents = {'xsd': ['annotation']}
  1534. tag = 'field'
  1535. class Unique(IdentityConstrants):
  1536. """<unique name> Enforce fields are unique w/i a specified scope.
  1537. parent:
  1538. element
  1539. attributes:
  1540. id -- ID
  1541. name -- NCName, required
  1542. contents:
  1543. annotation?, selector, field+
  1544. """
  1545. required = ['name']
  1546. attributes = {'id': None,
  1547. 'name': None}
  1548. contents = {'xsd': ['annotation', 'selector', 'field']}
  1549. tag = 'unique'
  1550. class Key(IdentityConstrants):
  1551. """<key name> Enforce fields are unique w/i a specified scope, and all
  1552. field values are present w/i document. Fields cannot
  1553. be nillable.
  1554. parent:
  1555. element
  1556. attributes:
  1557. id -- ID
  1558. name -- NCName, required
  1559. contents:
  1560. annotation?, selector, field+
  1561. """
  1562. required = ['name']
  1563. attributes = {'id': None,
  1564. 'name': None}
  1565. contents = {'xsd': ['annotation', 'selector', 'field']}
  1566. tag = 'key'
  1567. class KeyRef(IdentityConstrants):
  1568. """<keyref name refer> Ensure a match between two sets of values in an
  1569. instance.
  1570. parent:
  1571. element
  1572. attributes:
  1573. id -- ID
  1574. name -- NCName, required
  1575. refer -- QName, required
  1576. contents:
  1577. annotation?, selector, field+
  1578. """
  1579. required = ['name', 'refer']
  1580. attributes = {'id': None,
  1581. 'name': None,
  1582. 'refer': None}
  1583. contents = {'xsd': ['annotation', 'selector', 'field']}
  1584. tag = 'keyref'
  1585. class ElementDeclaration(XMLSchemaComponent,\
  1586. ElementMarker,\
  1587. DeclarationMarker):
  1588. """<element name>
  1589. parents:
  1590. schema
  1591. attributes:
  1592. id -- ID
  1593. name -- NCName, required
  1594. type -- QName
  1595. default -- string
  1596. fixed -- string
  1597. nillable -- boolean, false
  1598. abstract -- boolean, false
  1599. substitutionGroup -- QName
  1600. block -- ('#all' | ('substition' | 'extension' | 'restriction')*),
  1601. schema.blockDefault
  1602. final -- ('#all' | ('extension' | 'restriction')*),
  1603. schema.finalDefault
  1604. contents:
  1605. annotation?, (simpleType,complexType)?, (key | keyref | unique)*
  1606. """
  1607. required = ['name']
  1608. attributes = {'id': None,
  1609. 'name': None,
  1610. 'type': None,
  1611. 'default': None,
  1612. 'fixed': None,
  1613. 'nillable': 0,
  1614. 'abstract': 0,
  1615. 'substitutionGroup': None,
  1616. 'block': lambda self: self._parent().getBlockDefault(),
  1617. 'final': lambda self: self._parent().getFinalDefault()}
  1618. contents = {'xsd': ['annotation', 'simpleType', 'complexType', 'key',\
  1619. 'keyref', 'unique']}
  1620. tag = 'element'
  1621. def __init__(self, parent):
  1622. XMLSchemaComponent.__init__(self, parent)
  1623. self.annotation = None
  1624. self.content = None
  1625. self.constraints = ()
  1626. def isQualified(self):
  1627. """Global elements are always qualified.
  1628. """
  1629. return True
  1630. def getAttribute(self, attribute):
  1631. """return attribute.
  1632. If attribute is type and it's None, and no simple or complex content,
  1633. return the default type "xsd:anyType"
  1634. """
  1635. value = XMLSchemaComponent.getAttribute(self, attribute)
  1636. if attribute != 'type' or value is not None:
  1637. return value
  1638. if self.content is not None:
  1639. return None
  1640. parent = self
  1641. while 1:
  1642. nsdict = parent.attributes[XMLSchemaComponent.xmlns]
  1643. for k, v in nsdict.items():
  1644. if v not in SCHEMA.XSD_LIST:
  1645. continue
  1646. return TypeDescriptionComponent((v, 'anyType'))
  1647. if isinstance(parent, WSDLToolsAdapter)\
  1648. or not hasattr(parent, '_parent'):
  1649. break
  1650. parent = parent._parent()
  1651. raise SchemaError('failed to locate the XSD namespace')
  1652. def getElementDeclaration(self, attribute):
  1653. raise Warning('invalid operation for <%s>' % self.tag)
  1654. def getTypeDefinition(self, attribute=None):
  1655. """If attribute is None, "type" is assumed, return the corresponding
  1656. representation of the global type definition (TypeDefinition),
  1657. or the local definition if don't find "type". To maintain backwards
  1658. compat, if attribute is provided call base class method.
  1659. """
  1660. if attribute:
  1661. return XMLSchemaComponent.getTypeDefinition(self, attribute)
  1662. gt = XMLSchemaComponent.getTypeDefinition(self, 'type')
  1663. if gt:
  1664. return gt
  1665. return self.content
  1666. def getConstraints(self):
  1667. return self._constraints
  1668. def setConstraints(self, constraints):
  1669. self._constraints = tuple(constraints)
  1670. constraints = property(getConstraints, setConstraints, None, "tuple of key, keyref, unique constraints")
  1671. def fromDom(self, node):
  1672. self.setAttributes(node)
  1673. contents = self.getContents(node)
  1674. constraints = []
  1675. for i in contents:
  1676. component = SplitQName(i.getTagName())[1]
  1677. if component in self.__class__.contents['xsd']:
  1678. if component == 'annotation' and not self.annotation:
  1679. self.annotation = Annotation(self)
  1680. self.annotation.fromDom(i)
  1681. elif component == 'simpleType' and not self.content:
  1682. self.content = AnonymousSimpleType(self)
  1683. self.content.fromDom(i)
  1684. elif component == 'complexType' and not self.content:
  1685. self.content = LocalComplexType(self)
  1686. self.content.fromDom(i)
  1687. elif component == 'key':
  1688. constraints.append(Key(self))
  1689. constraints[-1].fromDom(i)
  1690. elif component == 'keyref':
  1691. constraints.append(KeyRef(self))
  1692. constraints[-1].fromDom(i)
  1693. elif component == 'unique':
  1694. constraints.append(Unique(self))
  1695. constraints[-1].fromDom(i)
  1696. else:
  1697. raise SchemaError('Unknown component (%s)' % (i.getTagName()))
  1698. else:
  1699. raise SchemaError('Unknown component (%s)' % (i.getTagName()))
  1700. self.constraints = constraints
  1701. class LocalElementDeclaration(ElementDeclaration,\
  1702. LocalMarker):
  1703. """<element>
  1704. parents:
  1705. all, choice, sequence
  1706. attributes:
  1707. id -- ID
  1708. name -- NCName, required
  1709. form -- ('qualified' | 'unqualified'), schema.elementFormDefault
  1710. type -- QName
  1711. minOccurs -- Whole Number, 1
  1712. maxOccurs -- (Whole Number | 'unbounded'), 1
  1713. default -- string
  1714. fixed -- string
  1715. nillable -- boolean, false
  1716. block -- ('#all' | ('extension' | 'restriction')*), schema.blockDefault
  1717. contents:
  1718. annotation?, (simpleType,complexType)?, (key | keyref | unique)*
  1719. """
  1720. required = ['name']
  1721. attributes = {'id': None,
  1722. 'name': None,
  1723. 'form': lambda self: GetSchema(self).getElementFormDefault(),
  1724. 'type': None,
  1725. 'minOccurs': '1',
  1726. 'maxOccurs': '1',
  1727. 'default': None,
  1728. 'fixed': None,
  1729. 'nillable': 0,
  1730. 'abstract': 0,
  1731. 'block': lambda self: GetSchema(self).getBlockDefault()}
  1732. contents = {'xsd': ['annotation', 'simpleType', 'complexType', 'key',\
  1733. 'keyref', 'unique']}
  1734. def isQualified(self):
  1735. """
  1736. Local elements can be qualified or unqualifed according
  1737. to the attribute form, or the elementFormDefault. By default
  1738. local elements are unqualified.
  1739. """
  1740. form = self.getAttribute('form')
  1741. if form == 'qualified':
  1742. return True
  1743. if form == 'unqualified':
  1744. return False
  1745. raise SchemaError('Bad form (%s) for element: %s' % (form, self.getItemTrace()))
  1746. class ElementReference(XMLSchemaComponent,\
  1747. ElementMarker,\
  1748. ReferenceMarker):
  1749. """<element ref>
  1750. parents:
  1751. all, choice, sequence
  1752. attributes:
  1753. id -- ID
  1754. ref -- QName, required
  1755. minOccurs -- Whole Number, 1
  1756. maxOccurs -- (Whole Number | 'unbounded'), 1
  1757. contents:
  1758. annotation?
  1759. """
  1760. required = ['ref']
  1761. attributes = {'id': None,
  1762. 'ref': None,
  1763. 'minOccurs': '1',
  1764. 'maxOccurs': '1'}
  1765. contents = {'xsd': ['annotation']}
  1766. tag = 'element'
  1767. def __init__(self, parent):
  1768. XMLSchemaComponent.__init__(self, parent)
  1769. self.annotation = None
  1770. def getElementDeclaration(self, attribute=None):
  1771. """If attribute is None, "ref" is assumed, return the corresponding
  1772. representation of the global element declaration (ElementDeclaration),
  1773. To maintain backwards compat, if attribute is provided call base class method.
  1774. """
  1775. if attribute:
  1776. return XMLSchemaComponent.getElementDeclaration(self, attribute)
  1777. return XMLSchemaComponent.getElementDeclaration(self, 'ref')
  1778. def fromDom(self, node):
  1779. self.annotation = None
  1780. self.setAttributes(node)
  1781. for i in self.getContents(node):
  1782. component = SplitQName(i.getTagName())[1]
  1783. if component in self.__class__.contents['xsd']:
  1784. if component == 'annotation' and not self.annotation:
  1785. self.annotation = Annotation(self)
  1786. self.annotation.fromDom(i)
  1787. else:
  1788. raise SchemaError('Unknown component (%s)' % (i.getTagName()))
  1789. class ElementWildCard(LocalElementDeclaration, WildCardMarker):
  1790. """<any>
  1791. parents:
  1792. choice, sequence
  1793. attributes:
  1794. id -- ID
  1795. minOccurs -- Whole Number, 1
  1796. maxOccurs -- (Whole Number | 'unbounded'), 1
  1797. namespace -- '##any' | '##other' |
  1798. (anyURI* | '##targetNamespace' | '##local'), ##any
  1799. processContents -- 'lax' | 'skip' | 'strict', strict
  1800. contents:
  1801. annotation?
  1802. """
  1803. required = []
  1804. attributes = {'id': None,
  1805. 'minOccurs': '1',
  1806. 'maxOccurs': '1',
  1807. 'namespace': '##any',
  1808. 'processContents': 'strict'}
  1809. contents = {'xsd': ['annotation']}
  1810. tag = 'any'
  1811. def __init__(self, parent):
  1812. XMLSchemaComponent.__init__(self, parent)
  1813. self.annotation = None
  1814. def isQualified(self):
  1815. """
  1816. Global elements are always qualified, but if processContents
  1817. are not strict could have dynamically generated local elements.
  1818. """
  1819. return GetSchema(self).isElementFormDefaultQualified()
  1820. def getAttribute(self, attribute):
  1821. """return attribute.
  1822. """
  1823. return XMLSchemaComponent.getAttribute(self, attribute)
  1824. def getTypeDefinition(self, attribute):
  1825. raise Warning('invalid operation for <%s>' % self.tag)
  1826. def fromDom(self, node):
  1827. self.annotation = None
  1828. self.setAttributes(node)
  1829. for i in self.getContents(node):
  1830. component = SplitQName(i.getTagName())[1]
  1831. if component in self.__class__.contents['xsd']:
  1832. if component == 'annotation' and not self.annotation:
  1833. self.annotation = Annotation(self)
  1834. self.annotation.fromDom(i)
  1835. else:
  1836. raise SchemaError('Unknown component (%s)' % (i.getTagName()))
  1837. ######################################################
  1838. # Model Groups
  1839. #####################################################
  1840. class Sequence(XMLSchemaComponent,\
  1841. SequenceMarker):
  1842. """<sequence>
  1843. parents:
  1844. complexType, extension, restriction, group, choice, sequence
  1845. attributes:
  1846. id -- ID
  1847. minOccurs -- Whole Number, 1
  1848. maxOccurs -- (Whole Number | 'unbounded'), 1
  1849. contents:
  1850. annotation?, (element | group | choice | sequence | any)*
  1851. """
  1852. attributes = {'id': None,
  1853. 'minOccurs': '1',
  1854. 'maxOccurs': '1'}
  1855. contents = {'xsd': ['annotation', 'element', 'group', 'choice', 'sequence',\
  1856. 'any']}
  1857. tag = 'sequence'
  1858. def __init__(self, parent):
  1859. XMLSchemaComponent.__init__(self, parent)
  1860. self.annotation = None
  1861. self.content = None
  1862. def fromDom(self, node):
  1863. self.setAttributes(node)
  1864. contents = self.getContents(node)
  1865. content = []
  1866. for i in contents:
  1867. component = SplitQName(i.getTagName())[1]
  1868. if component in self.__class__.contents['xsd']:
  1869. if component == 'annotation' and not self.annotation:
  1870. self.annotation = Annotation(self)
  1871. self.annotation.fromDom(i)
  1872. continue
  1873. elif component == 'element':
  1874. if i.hasattr('ref'):
  1875. content.append(ElementReference(self))
  1876. else:
  1877. content.append(LocalElementDeclaration(self))
  1878. elif component == 'group':
  1879. content.append(ModelGroupReference(self))
  1880. elif component == 'choice':
  1881. content.append(Choice(self))
  1882. elif component == 'sequence':
  1883. content.append(Sequence(self))
  1884. elif component == 'any':
  1885. content.append(ElementWildCard(self))
  1886. else:
  1887. raise SchemaError('Unknown component (%s)' % (i.getTagName()))
  1888. content[-1].fromDom(i)
  1889. else:
  1890. raise SchemaError('Unknown component (%s)' % (i.getTagName()))
  1891. self.content = tuple(content)
  1892. class All(XMLSchemaComponent,\
  1893. AllMarker):
  1894. """<all>
  1895. parents:
  1896. complexType, extension, restriction, group
  1897. attributes:
  1898. id -- ID
  1899. minOccurs -- '0' | '1', 1
  1900. maxOccurs -- '1', 1
  1901. contents:
  1902. annotation?, element*
  1903. """
  1904. attributes = {'id': None,
  1905. 'minOccurs': '1',
  1906. 'maxOccurs': '1'}
  1907. contents = {'xsd': ['annotation', 'element']}
  1908. tag = 'all'
  1909. def __init__(self, parent):
  1910. XMLSchemaComponent.__init__(self, parent)
  1911. self.annotation = None
  1912. self.content = None
  1913. def fromDom(self, node):
  1914. self.setAttributes(node)
  1915. contents = self.getContents(node)
  1916. content = []
  1917. for i in contents:
  1918. component = SplitQName(i.getTagName())[1]
  1919. if component in self.__class__.contents['xsd']:
  1920. if component == 'annotation' and not self.annotation:
  1921. self.annotation = Annotation(self)
  1922. self.annotation.fromDom(i)
  1923. continue
  1924. elif component == 'element':
  1925. if i.hasattr('ref'):
  1926. content.append(ElementReference(self))
  1927. else:
  1928. content.append(LocalElementDeclaration(self))
  1929. else:
  1930. raise SchemaError('Unknown component (%s)' % (i.getTagName()))
  1931. content[-1].fromDom(i)
  1932. else:
  1933. raise SchemaError('Unknown component (%s)' % (i.getTagName()))
  1934. self.content = tuple(content)
  1935. class Choice(XMLSchemaComponent,\
  1936. ChoiceMarker):
  1937. """<choice>
  1938. parents:
  1939. complexType, extension, restriction, group, choice, sequence
  1940. attributes:
  1941. id -- ID
  1942. minOccurs -- Whole Number, 1
  1943. maxOccurs -- (Whole Number | 'unbounded'), 1
  1944. contents:
  1945. annotation?, (element | group | choice | sequence | any)*
  1946. """
  1947. attributes = {'id': None,
  1948. 'minOccurs': '1',
  1949. 'maxOccurs': '1'}
  1950. contents = {'xsd': ['annotation', 'element', 'group', 'choice', 'sequence',\
  1951. 'any']}
  1952. tag = 'choice'
  1953. def __init__(self, parent):
  1954. XMLSchemaComponent.__init__(self, parent)
  1955. self.annotation = None
  1956. self.content = None
  1957. def fromDom(self, node):
  1958. self.setAttributes(node)
  1959. contents = self.getContents(node)
  1960. content = []
  1961. for i in contents:
  1962. component = SplitQName(i.getTagName())[1]
  1963. if component in self.__class__.contents['xsd']:
  1964. if component == 'annotation' and not self.annotation:
  1965. self.annotation = Annotation(self)
  1966. self.annotation.fromDom(i)
  1967. continue
  1968. elif component == 'element':
  1969. if i.hasattr('ref'):
  1970. content.append(ElementReference(self))
  1971. else:
  1972. content.append(LocalElementDeclaration(self))
  1973. elif component == 'group':
  1974. content.append(ModelGroupReference(self))
  1975. elif component == 'choice':
  1976. content.append(Choice(self))
  1977. elif component == 'sequence':
  1978. content.append(Sequence(self))
  1979. elif component == 'any':
  1980. content.append(ElementWildCard(self))
  1981. else:
  1982. raise SchemaError('Unknown component (%s)' % (i.getTagName()))
  1983. content[-1].fromDom(i)
  1984. else:
  1985. raise SchemaError('Unknown component (%s)' % (i.getTagName()))
  1986. self.content = tuple(content)
  1987. class ModelGroupDefinition(XMLSchemaComponent,\
  1988. ModelGroupMarker,\
  1989. DefinitionMarker):
  1990. """<group name>
  1991. parents:
  1992. redefine, schema
  1993. attributes:
  1994. id -- ID
  1995. name -- NCName, required
  1996. contents:
  1997. annotation?, (all | choice | sequence)?
  1998. """
  1999. required = ['name']
  2000. attributes = {'id': None,
  2001. 'name': None}
  2002. contents = {'xsd': ['annotation', 'all', 'choice', 'sequence']}
  2003. tag = 'group'
  2004. def __init__(self, parent):
  2005. XMLSchemaComponent.__init__(self, parent)
  2006. self.annotation = None
  2007. self.content = None
  2008. def fromDom(self, node):
  2009. self.setAttributes(node)
  2010. contents = self.getContents(node)
  2011. for i in contents:
  2012. component = SplitQName(i.getTagName())[1]
  2013. if component in self.__class__.contents['xsd']:
  2014. if component == 'annotation' and not self.annotation:
  2015. self.annotation = Annotation(self)
  2016. self.annotation.fromDom(i)
  2017. continue
  2018. elif component == 'all' and not self.content:
  2019. self.content = All(self)
  2020. elif component == 'choice' and not self.content:
  2021. self.content = Choice(self)
  2022. elif component == 'sequence' and not self.content:
  2023. self.content = Sequence(self)
  2024. else:
  2025. raise SchemaError('Unknown component (%s)' % (i.getTagName()))
  2026. self.content.fromDom(i)
  2027. else:
  2028. raise SchemaError('Unknown component (%s)' % (i.getTagName()))
  2029. class ModelGroupReference(XMLSchemaComponent,\
  2030. ModelGroupMarker,\
  2031. ReferenceMarker):
  2032. """<group ref>
  2033. parents:
  2034. choice, complexType, extension, restriction, sequence
  2035. attributes:
  2036. id -- ID
  2037. ref -- NCName, required
  2038. minOccurs -- Whole Number, 1
  2039. maxOccurs -- (Whole Number | 'unbounded'), 1
  2040. contents:
  2041. annotation?
  2042. """
  2043. required = ['ref']
  2044. attributes = {'id': None,
  2045. 'ref': None,
  2046. 'minOccurs': '1',
  2047. 'maxOccurs': '1'}
  2048. contents = {'xsd': ['annotation']}
  2049. tag = 'group'
  2050. def __init__(self, parent):
  2051. XMLSchemaComponent.__init__(self, parent)
  2052. self.annotation = None
  2053. def getModelGroupReference(self):
  2054. return self.getModelGroup('ref')
  2055. def fromDom(self, node):
  2056. self.setAttributes(node)
  2057. contents = self.getContents(node)
  2058. for i in contents:
  2059. component = SplitQName(i.getTagName())[1]
  2060. if component in self.__class__.contents['xsd']:
  2061. if component == 'annotation' and not self.annotation:
  2062. self.annotation = Annotation(self)
  2063. self.annotation.fromDom(i)
  2064. else:
  2065. raise SchemaError('Unknown component (%s)' % (i.getTagName()))
  2066. else:
  2067. raise SchemaError('Unknown component (%s)' % (i.getTagName()))
  2068. class ComplexType(XMLSchemaComponent,\
  2069. DefinitionMarker,\
  2070. ComplexMarker):
  2071. """<complexType name>
  2072. parents:
  2073. redefine, schema
  2074. attributes:
  2075. id -- ID
  2076. name -- NCName, required
  2077. mixed -- boolean, false
  2078. abstract -- boolean, false
  2079. block -- ('#all' | ('extension' | 'restriction')*), schema.blockDefault
  2080. final -- ('#all' | ('extension' | 'restriction')*), schema.finalDefault
  2081. contents:
  2082. annotation?, (simpleContent | complexContent |
  2083. ((group | all | choice | sequence)?, (attribute | attributeGroup)*, anyAttribute?))
  2084. """
  2085. required = ['name']
  2086. attributes = {'id': None,
  2087. 'name': None,
  2088. 'mixed': 0,
  2089. 'abstract': 0,
  2090. 'block': lambda self: self._parent().getBlockDefault(),
  2091. 'final': lambda self: self._parent().getFinalDefault()}
  2092. contents = {'xsd': ['annotation', 'simpleContent', 'complexContent',\
  2093. 'group', 'all', 'choice', 'sequence', 'attribute', 'attributeGroup',\
  2094. 'anyAttribute', 'any']}
  2095. tag = 'complexType'
  2096. def __init__(self, parent):
  2097. XMLSchemaComponent.__init__(self, parent)
  2098. self.annotation = None
  2099. self.content = None
  2100. self.attr_content = None
  2101. def isMixed(self):
  2102. m = self.getAttribute('mixed')
  2103. if not m:
  2104. return False
  2105. if isinstance(m, basestring):
  2106. if m in ('false', '0'):
  2107. return False
  2108. if m in ('true', '1'):
  2109. return True
  2110. raise SchemaError('invalid value for attribute mixed(%s): %s' % (m, self.getItemTrace()))
  2111. def getAttributeContent(self):
  2112. return self.attr_content
  2113. def getElementDeclaration(self, attribute):
  2114. raise Warning('invalid operation for <%s>' % self.tag)
  2115. def getTypeDefinition(self, attribute):
  2116. raise Warning('invalid operation for <%s>' % self.tag)
  2117. def fromDom(self, node):
  2118. self.setAttributes(node)
  2119. contents = self.getContents(node)
  2120. indx = 0
  2121. num = len(contents)
  2122. if not num:
  2123. return
  2124. component = SplitQName(contents[indx].getTagName())[1]
  2125. if component == 'annotation':
  2126. self.annotation = Annotation(self)
  2127. self.annotation.fromDom(contents[indx])
  2128. indx += 1
  2129. if indx < num:
  2130. component = SplitQName(contents[indx].getTagName())[1]
  2131. self.content = None
  2132. if component == 'simpleContent':
  2133. self.content = self.__class__.SimpleContent(self)
  2134. self.content.fromDom(contents[indx])
  2135. elif component == 'complexContent':
  2136. self.content = self.__class__.ComplexContent(self)
  2137. self.content.fromDom(contents[indx])
  2138. else:
  2139. if component == 'all':
  2140. self.content = All(self)
  2141. elif component == 'choice':
  2142. self.content = Choice(self)
  2143. elif component == 'sequence':
  2144. self.content = Sequence(self)
  2145. elif component == 'group':
  2146. self.content = ModelGroupReference(self)
  2147. if self.content:
  2148. self.content.fromDom(contents[indx])
  2149. indx += 1
  2150. self.attr_content = []
  2151. while indx < num:
  2152. component = SplitQName(contents[indx].getTagName())[1]
  2153. if component == 'attribute':
  2154. if contents[indx].hasattr('ref'):
  2155. self.attr_content.append(AttributeReference(self))
  2156. else:
  2157. self.attr_content.append(LocalAttributeDeclaration(self))
  2158. elif component == 'attributeGroup':
  2159. self.attr_content.append(AttributeGroupReference(self))
  2160. elif component == 'anyAttribute':
  2161. self.attr_content.append(AttributeWildCard(self))
  2162. else:
  2163. raise SchemaError('Unknown component (%s): %s' % (contents[indx].getTagName(), self.getItemTrace()))
  2164. self.attr_content[-1].fromDom(contents[indx])
  2165. indx += 1
  2166. class _DerivedType(XMLSchemaComponent):
  2167. def __init__(self, parent):
  2168. XMLSchemaComponent.__init__(self, parent)
  2169. self.annotation = None
  2170. # XXX remove attribute derivation, inconsistent
  2171. self.derivation = None
  2172. self.content = None
  2173. def fromDom(self, node):
  2174. self.setAttributes(node)
  2175. contents = self.getContents(node)
  2176. for i in contents:
  2177. component = SplitQName(i.getTagName())[1]
  2178. if component in self.__class__.contents['xsd']:
  2179. if component == 'annotation' and not self.annotation:
  2180. self.annotation = Annotation(self)
  2181. self.annotation.fromDom(i)
  2182. continue
  2183. elif component == 'restriction' and not self.derivation:
  2184. self.derivation = self.__class__.Restriction(self)
  2185. elif component == 'extension' and not self.derivation:
  2186. self.derivation = self.__class__.Extension(self)
  2187. else:
  2188. raise SchemaError('Unknown component (%s)' % (i.getTagName()))
  2189. else:
  2190. raise SchemaError('Unknown component (%s)' % (i.getTagName()))
  2191. self.derivation.fromDom(i)
  2192. self.content = self.derivation
  2193. class ComplexContent(_DerivedType,\
  2194. ComplexMarker):
  2195. """<complexContent>
  2196. parents:
  2197. complexType
  2198. attributes:
  2199. id -- ID
  2200. mixed -- boolean, false
  2201. contents:
  2202. annotation?, (restriction | extension)
  2203. """
  2204. attributes = {'id': None,
  2205. 'mixed': 0}
  2206. contents = {'xsd': ['annotation', 'restriction', 'extension']}
  2207. tag = 'complexContent'
  2208. def isMixed(self):
  2209. m = self.getAttribute('mixed')
  2210. if not m:
  2211. return False
  2212. if isinstance(m, basestring) is True:
  2213. if m in ('false', '0'):
  2214. return False
  2215. if m in ('true', '1'):
  2216. return True
  2217. raise SchemaError('invalid value for attribute mixed(%s): %s' % (m, self.getItemTrace()))
  2218. class _DerivationBase(XMLSchemaComponent):
  2219. """<extension>,<restriction>
  2220. parents:
  2221. complexContent
  2222. attributes:
  2223. id -- ID
  2224. base -- QName, required
  2225. contents:
  2226. annotation?, (group | all | choice | sequence)?,
  2227. (attribute | attributeGroup)*, anyAttribute?
  2228. """
  2229. required = ['base']
  2230. attributes = {'id': None,
  2231. 'base': None}
  2232. contents = {'xsd': ['annotation', 'group', 'all', 'choice',\
  2233. 'sequence', 'attribute', 'attributeGroup', 'anyAttribute']}
  2234. def __init__(self, parent):
  2235. XMLSchemaComponent.__init__(self, parent)
  2236. self.annotation = None
  2237. self.content = None
  2238. self.attr_content = None
  2239. def getAttributeContent(self):
  2240. return self.attr_content
  2241. def fromDom(self, node):
  2242. self.setAttributes(node)
  2243. contents = self.getContents(node)
  2244. indx = 0
  2245. num = len(contents)
  2246. #XXX ugly
  2247. if not num:
  2248. return
  2249. component = SplitQName(contents[indx].getTagName())[1]
  2250. if component == 'annotation':
  2251. self.annotation = Annotation(self)
  2252. self.annotation.fromDom(contents[indx])
  2253. indx += 1
  2254. component = SplitQName(contents[indx].getTagName())[1]
  2255. if component == 'all':
  2256. self.content = All(self)
  2257. self.content.fromDom(contents[indx])
  2258. indx += 1
  2259. elif component == 'choice':
  2260. self.content = Choice(self)
  2261. self.content.fromDom(contents[indx])
  2262. indx += 1
  2263. elif component == 'sequence':
  2264. self.content = Sequence(self)
  2265. self.content.fromDom(contents[indx])
  2266. indx += 1
  2267. elif component == 'group':
  2268. self.content = ModelGroupReference(self)
  2269. self.content.fromDom(contents[indx])
  2270. indx += 1
  2271. else:
  2272. self.content = None
  2273. self.attr_content = []
  2274. while indx < num:
  2275. component = SplitQName(contents[indx].getTagName())[1]
  2276. if component == 'attribute':
  2277. if contents[indx].hasattr('ref'):
  2278. self.attr_content.append(AttributeReference(self))
  2279. else:
  2280. self.attr_content.append(LocalAttributeDeclaration(self))
  2281. elif component == 'attributeGroup':
  2282. if contents[indx].hasattr('ref'):
  2283. self.attr_content.append(AttributeGroupReference(self))
  2284. else:
  2285. self.attr_content.append(AttributeGroupDefinition(self))
  2286. elif component == 'anyAttribute':
  2287. self.attr_content.append(AttributeWildCard(self))
  2288. else:
  2289. raise SchemaError('Unknown component (%s)' % (contents[indx].getTagName()))
  2290. self.attr_content[-1].fromDom(contents[indx])
  2291. indx += 1
  2292. class Extension(_DerivationBase,
  2293. ExtensionMarker):
  2294. """<extension base>
  2295. parents:
  2296. complexContent
  2297. attributes:
  2298. id -- ID
  2299. base -- QName, required
  2300. contents:
  2301. annotation?, (group | all | choice | sequence)?,
  2302. (attribute | attributeGroup)*, anyAttribute?
  2303. """
  2304. tag = 'extension'
  2305. class Restriction(_DerivationBase,\
  2306. RestrictionMarker):
  2307. """<restriction base>
  2308. parents:
  2309. complexContent
  2310. attributes:
  2311. id -- ID
  2312. base -- QName, required
  2313. contents:
  2314. annotation?, (group | all | choice | sequence)?,
  2315. (attribute | attributeGroup)*, anyAttribute?
  2316. """
  2317. tag = 'restriction'
  2318. class SimpleContent(_DerivedType,\
  2319. SimpleMarker):
  2320. """<simpleContent>
  2321. parents:
  2322. complexType
  2323. attributes:
  2324. id -- ID
  2325. contents:
  2326. annotation?, (restriction | extension)
  2327. """
  2328. attributes = {'id': None}
  2329. contents = {'xsd': ['annotation', 'restriction', 'extension']}
  2330. tag = 'simpleContent'
  2331. class Extension(XMLSchemaComponent,\
  2332. ExtensionMarker):
  2333. """<extension base>
  2334. parents:
  2335. simpleContent
  2336. attributes:
  2337. id -- ID
  2338. base -- QName, required
  2339. contents:
  2340. annotation?, (attribute | attributeGroup)*, anyAttribute?
  2341. """
  2342. required = ['base']
  2343. attributes = {'id': None,
  2344. 'base': None}
  2345. contents = {'xsd': ['annotation', 'attribute', 'attributeGroup',
  2346. 'anyAttribute']}
  2347. tag = 'extension'
  2348. def __init__(self, parent):
  2349. XMLSchemaComponent.__init__(self, parent)
  2350. self.annotation = None
  2351. self.attr_content = None
  2352. def getAttributeContent(self):
  2353. return self.attr_content
  2354. def fromDom(self, node):
  2355. self.setAttributes(node)
  2356. contents = self.getContents(node)
  2357. indx = 0
  2358. num = len(contents)
  2359. if num:
  2360. component = SplitQName(contents[indx].getTagName())[1]
  2361. if component == 'annotation':
  2362. self.annotation = Annotation(self)
  2363. self.annotation.fromDom(contents[indx])
  2364. indx += 1
  2365. component = SplitQName(contents[indx].getTagName())[1]
  2366. content = []
  2367. while indx < num:
  2368. component = SplitQName(contents[indx].getTagName())[1]
  2369. if component == 'attribute':
  2370. if contents[indx].hasattr('ref'):
  2371. content.append(AttributeReference(self))
  2372. else:
  2373. content.append(LocalAttributeDeclaration(self))
  2374. elif component == 'attributeGroup':
  2375. content.append(AttributeGroupReference(self))
  2376. elif component == 'anyAttribute':
  2377. content.append(AttributeWildCard(self))
  2378. else:
  2379. raise SchemaError('Unknown component (%s)' % (contents[indx].getTagName()))
  2380. content[-1].fromDom(contents[indx])
  2381. indx += 1
  2382. self.attr_content = tuple(content)
  2383. class Restriction(XMLSchemaComponent,\
  2384. RestrictionMarker):
  2385. """<restriction base>
  2386. parents:
  2387. simpleContent
  2388. attributes:
  2389. id -- ID
  2390. base -- QName, required
  2391. contents:
  2392. annotation?, simpleType?, (enumeration | length |
  2393. maxExclusive | maxInclusive | maxLength | minExclusive |
  2394. minInclusive | minLength | pattern | fractionDigits |
  2395. totalDigits | whiteSpace)*, (attribute | attributeGroup)*,
  2396. anyAttribute?
  2397. """
  2398. required = ['base']
  2399. attributes = {'id': None,
  2400. 'base': None}
  2401. contents = {'xsd': ['annotation', 'simpleType', 'attribute',\
  2402. 'attributeGroup', 'anyAttribute'] + RestrictionMarker.facets}
  2403. tag = 'restriction'
  2404. def __init__(self, parent):
  2405. XMLSchemaComponent.__init__(self, parent)
  2406. self.annotation = None
  2407. self.content = None
  2408. self.attr_content = None
  2409. def getAttributeContent(self):
  2410. return self.attr_content
  2411. def fromDom(self, node):
  2412. self.content = []
  2413. self.setAttributes(node)
  2414. contents = self.getContents(node)
  2415. indx = 0
  2416. num = len(contents)
  2417. component = SplitQName(contents[indx].getTagName())[1]
  2418. if component == 'annotation':
  2419. self.annotation = Annotation(self)
  2420. self.annotation.fromDom(contents[indx])
  2421. indx += 1
  2422. component = SplitQName(contents[indx].getTagName())[1]
  2423. content = []
  2424. while indx < num:
  2425. component = SplitQName(contents[indx].getTagName())[1]
  2426. if component == 'attribute':
  2427. if contents[indx].hasattr('ref'):
  2428. content.append(AttributeReference(self))
  2429. else:
  2430. content.append(LocalAttributeDeclaration(self))
  2431. elif component == 'attributeGroup':
  2432. content.append(AttributeGroupReference(self))
  2433. elif component == 'anyAttribute':
  2434. content.append(AttributeWildCard(self))
  2435. elif component == 'simpleType':
  2436. self.content.append(AnonymousSimpleType(self))
  2437. self.content[-1].fromDom(contents[indx])
  2438. else:
  2439. raise SchemaError('Unknown component (%s)' % (contents[indx].getTagName()))
  2440. content[-1].fromDom(contents[indx])
  2441. indx += 1
  2442. self.attr_content = tuple(content)
  2443. class LocalComplexType(ComplexType,\
  2444. LocalMarker):
  2445. """<complexType>
  2446. parents:
  2447. element
  2448. attributes:
  2449. id -- ID
  2450. mixed -- boolean, false
  2451. contents:
  2452. annotation?, (simpleContent | complexContent |
  2453. ((group | all | choice | sequence)?, (attribute | attributeGroup)*, anyAttribute?))
  2454. """
  2455. required = []
  2456. attributes = {'id': None,
  2457. 'mixed': 0}
  2458. tag = 'complexType'
  2459. class SimpleType(XMLSchemaComponent,\
  2460. DefinitionMarker,\
  2461. SimpleMarker):
  2462. """<simpleType name>
  2463. parents:
  2464. redefine, schema
  2465. attributes:
  2466. id -- ID
  2467. name -- NCName, required
  2468. final -- ('#all' | ('extension' | 'restriction' | 'list' | 'union')*),
  2469. schema.finalDefault
  2470. contents:
  2471. annotation?, (restriction | list | union)
  2472. """
  2473. required = ['name']
  2474. attributes = {'id': None,
  2475. 'name': None,
  2476. 'final': lambda self: self._parent().getFinalDefault()}
  2477. contents = {'xsd': ['annotation', 'restriction', 'list', 'union']}
  2478. tag = 'simpleType'
  2479. def __init__(self, parent):
  2480. XMLSchemaComponent.__init__(self, parent)
  2481. self.annotation = None
  2482. self.content = None
  2483. def getElementDeclaration(self, attribute):
  2484. raise Warning('invalid operation for <%s>' % self.tag)
  2485. def getTypeDefinition(self, attribute):
  2486. raise Warning('invalid operation for <%s>' % self.tag)
  2487. def fromDom(self, node):
  2488. self.setAttributes(node)
  2489. contents = self.getContents(node)
  2490. for child in contents:
  2491. component = SplitQName(child.getTagName())[1]
  2492. if component == 'annotation':
  2493. self.annotation = Annotation(self)
  2494. self.annotation.fromDom(child)
  2495. continue
  2496. break
  2497. else:
  2498. return
  2499. if component == 'restriction':
  2500. self.content = self.__class__.Restriction(self)
  2501. elif component == 'list':
  2502. self.content = self.__class__.List(self)
  2503. elif component == 'union':
  2504. self.content = self.__class__.Union(self)
  2505. else:
  2506. raise SchemaError('Unknown component (%s)' % (component))
  2507. self.content.fromDom(child)
  2508. class Restriction(XMLSchemaComponent,\
  2509. RestrictionMarker):
  2510. """<restriction base>
  2511. parents:
  2512. simpleType
  2513. attributes:
  2514. id -- ID
  2515. base -- QName, required or simpleType child
  2516. contents:
  2517. annotation?, simpleType?, (enumeration | length |
  2518. maxExclusive | maxInclusive | maxLength | minExclusive |
  2519. minInclusive | minLength | pattern | fractionDigits |
  2520. totalDigits | whiteSpace)*
  2521. """
  2522. attributes = {'id': None,
  2523. 'base': None}
  2524. contents = {'xsd': ['annotation', 'simpleType'] + RestrictionMarker.facets}
  2525. tag = 'restriction'
  2526. def __init__(self, parent):
  2527. XMLSchemaComponent.__init__(self, parent)
  2528. self.annotation = None
  2529. self.content = None
  2530. self.facets = None
  2531. def getAttributeBase(self):
  2532. return XMLSchemaComponent.getAttribute(self, 'base')
  2533. def getTypeDefinition(self, attribute='base'):
  2534. return XMLSchemaComponent.getTypeDefinition(self, attribute)
  2535. def getSimpleTypeContent(self):
  2536. for el in self.content:
  2537. if el.isSimple():
  2538. return el
  2539. return None
  2540. def fromDom(self, node):
  2541. self.facets = []
  2542. self.setAttributes(node)
  2543. contents = self.getContents(node)
  2544. content = []
  2545. for indx in range(len(contents)):
  2546. component = SplitQName(contents[indx].getTagName())[1]
  2547. if (component == 'annotation') and (not indx):
  2548. self.annotation = Annotation(self)
  2549. self.annotation.fromDom(contents[indx])
  2550. continue
  2551. elif (component == 'simpleType') and (not indx or indx == 1):
  2552. content.append(AnonymousSimpleType(self))
  2553. content[-1].fromDom(contents[indx])
  2554. elif component in RestrictionMarker.facets:
  2555. self.facets.append(contents[indx])
  2556. else:
  2557. raise SchemaError('Unknown component (%s)' % (i.getTagName()))
  2558. self.content = tuple(content)
  2559. class Union(XMLSchemaComponent,
  2560. UnionMarker):
  2561. """<union>
  2562. parents:
  2563. simpleType
  2564. attributes:
  2565. id -- ID
  2566. memberTypes -- list of QNames, required or simpleType child.
  2567. contents:
  2568. annotation?, simpleType*
  2569. """
  2570. attributes = {'id': None,
  2571. 'memberTypes': None}
  2572. contents = {'xsd': ['annotation', 'simpleType']}
  2573. tag = 'union'
  2574. def __init__(self, parent):
  2575. XMLSchemaComponent.__init__(self, parent)
  2576. self.annotation = None
  2577. self.content = None
  2578. def fromDom(self, node):
  2579. self.setAttributes(node)
  2580. contents = self.getContents(node)
  2581. content = []
  2582. for indx in range(len(contents)):
  2583. component = SplitQName(contents[indx].getTagName())[1]
  2584. if (component == 'annotation') and (not indx):
  2585. self.annotation = Annotation(self)
  2586. self.annotation.fromDom(contents[indx])
  2587. elif (component == 'simpleType'):
  2588. content.append(AnonymousSimpleType(self))
  2589. content[-1].fromDom(contents[indx])
  2590. else:
  2591. raise SchemaError('Unknown component (%s)' % (i.getTagName()))
  2592. self.content = tuple(content)
  2593. class List(XMLSchemaComponent,
  2594. ListMarker):
  2595. """<list>
  2596. parents:
  2597. simpleType
  2598. attributes:
  2599. id -- ID
  2600. itemType -- QName, required or simpleType child.
  2601. contents:
  2602. annotation?, simpleType?
  2603. """
  2604. attributes = {'id': None,
  2605. 'itemType': None}
  2606. contents = {'xsd': ['annotation', 'simpleType']}
  2607. tag = 'list'
  2608. def __init__(self, parent):
  2609. XMLSchemaComponent.__init__(self, parent)
  2610. self.annotation = None
  2611. self.content = None
  2612. def getItemType(self):
  2613. return self.attributes.get('itemType')
  2614. def getTypeDefinition(self, attribute='itemType'):
  2615. """
  2616. return the type refered to by itemType attribute or
  2617. the simpleType content. If returns None, then the
  2618. type refered to by itemType is primitive.
  2619. """
  2620. tp = XMLSchemaComponent.getTypeDefinition(self, attribute)
  2621. return tp or self.content
  2622. def fromDom(self, node):
  2623. self.annotation = None
  2624. self.content = None
  2625. self.setAttributes(node)
  2626. contents = self.getContents(node)
  2627. for indx in range(len(contents)):
  2628. component = SplitQName(contents[indx].getTagName())[1]
  2629. if (component == 'annotation') and (not indx):
  2630. self.annotation = Annotation(self)
  2631. self.annotation.fromDom(contents[indx])
  2632. elif (component == 'simpleType'):
  2633. self.content = AnonymousSimpleType(self)
  2634. self.content.fromDom(contents[indx])
  2635. break
  2636. else:
  2637. raise SchemaError('Unknown component (%s)' % (i.getTagName()))
  2638. class AnonymousSimpleType(SimpleType,\
  2639. SimpleMarker,\
  2640. LocalMarker):
  2641. """<simpleType>
  2642. parents:
  2643. attribute, element, list, restriction, union
  2644. attributes:
  2645. id -- ID
  2646. contents:
  2647. annotation?, (restriction | list | union)
  2648. """
  2649. required = []
  2650. attributes = {'id': None}
  2651. tag = 'simpleType'
  2652. class Redefine:
  2653. """<redefine>
  2654. parents:
  2655. attributes:
  2656. contents:
  2657. """
  2658. tag = 'redefine'
  2659. ###########################
  2660. ###########################
  2661. if sys.version_info[:2] >= (2, 2):
  2662. tupleClass = tuple
  2663. else:
  2664. import UserTuple
  2665. tupleClass = UserTuple.UserTuple
  2666. class TypeDescriptionComponent(tupleClass):
  2667. """Tuple of length 2, consisting of
  2668. a namespace and unprefixed name.
  2669. """
  2670. def __new__(typ, args):
  2671. """args -- (namespace, name)
  2672. Remove the name's prefix, irrelevant.
  2673. """
  2674. if len(args) != 2:
  2675. raise TypeError('expecting tuple (namespace, name), got %s' % args)
  2676. elif args[1].find(':') >= 0:
  2677. args = (args[0], SplitQName(args[1])[1])
  2678. return tuple.__new__(typ, args)
  2679. def getTargetNamespace(self):
  2680. return self[0]
  2681. def getName(self):
  2682. return self[1]