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.
 
 
 

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