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.
 
 
 

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