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.
 
 
 

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