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.
 
 
 

3116 lines
107 KiB

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