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.
 
 
 

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