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.
 
 
 

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