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.
 
 
 

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