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.
 
 
 

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