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.
 
 
 

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