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.
 
 
 

2822 lines
96 KiB

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