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.
 
 
 

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