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.
 
 
 

3122 lines
107 KiB

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