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.
 
 
 

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