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.
 
 
 

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