#!/usr/bin/env python ## LICENSE ## Copyright (c) 2003 Dave Kuhlman ## Permission is hereby granted, free of charge, to any person obtaining ## a copy of this software and associated documentation files (the ## "Software"), to deal in the Software without restriction, including ## without limitation the rights to use, copy, modify, merge, publish, ## distribute, sublicense, and/or sell copies of the Software, and to ## permit persons to whom the Software is furnished to do so, subject to ## the following conditions: ## The above copyright notice and this permission notice shall be ## included in all copies or substantial portions of the Software. ## THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, ## EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF ## MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. ## IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY ## CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, ## TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE ## SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #from __future__ import generators # only needed for Python 2.2 import sys import os.path import time import getopt import urllib2 from xml.sax import handler, make_parser import xml.sax.xmlreader ##from IPython.Shell import IPShellEmbed ##args = '' ##ipshell = IPShellEmbed(args, ## banner = 'Dropping into IPython', ## exit_msg = 'Leaving Interpreter, back to program.') # Then use the following line where and when you want to drop into the # IPython shell: # ipshell(' -- Entering ipshell.\\nHit Ctrl-D to exit') # # Global variables etc. # GenerateProperties = 0 DelayedElements = [] DelayedElements_subclass = [] AlreadyGenerated = [] AlreadyGenerated_subclass = [] PostponedExtensions = [] ElementsForSubclasses = [] ElementDict = {} SaxElementDict = {} ElementDebugList = [] Force = 0 NameTable = { 'class': 'klass', 'import': 'emport', 'type': 'ttype', } SubclassSuffix = 'Sub' RootElement = None AttributeGroups = {} SubstitutionGroups = {} # # SubstitutionGroups can also include simple types that are # not (defined) elements. Keep a list of these simple types. # These are simple types defined at top level. SimpleElementDict = {} def set_type_constants(nameSpace): global StringType, TokenType, \ IntegerType, DecimalType, \ ShortType, LongType, \ PositiveIntegerType, NegativeIntegerType, \ NonPositiveIntegerType, NonNegativeIntegerType, \ BooleanType, FloatType, DoubleType, \ ElementType, ComplexTypeType, SequenceType, ChoiceType, \ AttributeGroupType, AttributeType, SchemaType, \ DateTimeType, DateType, \ ComplexContentType, ExtensionType, \ IDType, IDREFType, IDREFSType, \ AnyAttributeType AttributeGroupType = nameSpace + 'attributeGroup' AttributeType = nameSpace + 'attribute' BooleanType = nameSpace + 'boolean' ChoiceType = nameSpace + 'choice' ComplexContentType = nameSpace + 'complexContent' ComplexTypeType = nameSpace + 'complexType' AnyAttributeType = nameSpace + 'anyAttribute' DateTimeType = nameSpace + 'dateTime' DateType = nameSpace + 'date' IntegerType = (nameSpace + 'integer', nameSpace + 'xs:unsignedShort', nameSpace + 'short', nameSpace + 'long', ) #ShortType = nameSpace + 'short' #LongType = nameSpace + 'long' DecimalType = nameSpace + 'decimal' PositiveIntegerType = nameSpace + 'positiveInteger' NegativeIntegerType = nameSpace + 'negativeInteger' NonPositiveIntegerType = nameSpace + 'nonPositiveInteger' NonNegativeIntegerType = nameSpace + 'nonNegativeInteger' DoubleType = nameSpace + 'double' ElementType = nameSpace + 'element' ExtensionType = nameSpace + 'extension' FloatType = nameSpace + 'float' IDREFSType = nameSpace + 'IDREFS' IDREFType = nameSpace + 'IDREF' IDType = nameSpace + 'ID' SchemaType = nameSpace + 'schema' SequenceType = nameSpace + 'sequence' StringType = (nameSpace + 'string', nameSpace + 'duration', nameSpace + 'anyURI', ) TokenType = nameSpace + 'token' # # For debugging. # # Print only if DEBUG is true. DEBUG = 1 def dbgprint(level, msg): if DEBUG and level > 0: print msg def pplist(lst): for count, item in enumerate(lst): print '%d. %s' % (count, item) # # Representation of element definition. # def showLevel(outfile, level): for idx in range(level): outfile.write(' ') class XschemaElement: def __init__(self, attrs): self.cleanName = '' self.attrs = dict(attrs) name_val = '' type_val = '' ref_val = '' if 'name' in self.attrs: name_val = strip_namespace(self.attrs['name']) if 'type' in self.attrs: # fix #type_val = strip_namespace(self.attrs['type']) type_val = self.attrs['type'] if 'ref' in self.attrs: ref_val = strip_namespace(self.attrs['ref']) if type_val and not name_val: name_val = type_val if ref_val and not name_val: name_val = ref_val if ref_val and not type_val: type_val = ref_val if name_val: self.attrs['name'] = name_val if type_val: self.attrs['type'] = type_val if ref_val: self.attrs['ref'] = ref_val self.name = name_val self.children = [] self.maxOccurs = 1 self.complex = 0 self.complexType = 0 self.type = 'NoneType' self.mixed = 0 self.base = None self.mixedExtensionError = 0 # Attribute definitions for the currect element. self.attributeDefs = {} # Attribute definitions for the current attributeGroup, if there is one. self.attributeGroup = None # List of names of attributes for this element. # We will add the attribute defintions in each of these groups # to this element in annotate(). self.attributeGroupNameList = [] self.topLevel = 0 # Does this element contain an anyAttribute? self.anyAttribute = 0 def addChild(self, element): self.children.append(element) def getChildren(self): return self.children def getName(self): return self.name def getCleanName(self): return self.cleanName def getUnmappedCleanName(self): return self.unmappedCleanName def setName(self, name): self.name = name def getAttrs(self): return self.attrs def setAttrs(self, attrs): self.attrs = attrs def getMaxOccurs(self): return self.maxOccurs def getRawType(self): return self.type def getType(self): returnType = self.type if self.type in ElementDict: typeObj = ElementDict[self.type] typeObjType = typeObj.getRawType() if typeObjType in StringType or \ typeObjType == TokenType or \ typeObjType == DateTimeType or \ typeObjType == DateType or \ typeObjType in IntegerType or \ typeObjType == DecimalType or \ typeObjType == PositiveIntegerType or \ typeObjType == NegativeIntegerType or \ typeObjType == NonPositiveIntegerType or \ typeObjType == NonNegativeIntegerType or \ typeObjType == BooleanType or \ typeObjType == FloatType or \ typeObjType == DoubleType: returnType = typeObjType return returnType def isComplex(self): return self.complex def addAttributeDefs(self, attrs): self.attributeDefs.append(attrs) def getAttributeDefs(self): return self.attributeDefs def isMixed(self): return self.mixed def setMixed(self, mixed): self.mixed = mixed def setBase(self, base): self.base = base def getBase(self): return self.base def getMixedExtensionError(self): return self.mixedExtensionError def getAttributeGroups(self): return self.attributeGroups def addAttribute(self, name, attribute): self.attributeGroups[name] = attribute def setAttributeGroup(self, attributeGroup): self.attributeGroup = attributeGroup def getAttributeGroup(self): return self.attributeGroup def setTopLevel(self, topLevel): self.topLevel = topLevel def getTopLevel(self): return self.topLevel def setAnyAttribute(self, anyAttribute): self.anyAttribute = anyAttribute def getAnyAttribute(self): return self.anyAttribute def show(self, outfile, level): showLevel(outfile, level) outfile.write('Name: %s Type: %s\n' % (self.name, self.getType())) showLevel(outfile, level) outfile.write(' - Complex: %d MaxOccurs: %d\n' % \ (self.complex, self.maxOccurs)) showLevel(outfile, level) outfile.write(' - Attrs: %s\n' % self.attrs) showLevel(outfile, level) outfile.write(' - AttributeDefs: %s\n' % self.attributeDefs) #ipshell('(visit_title) Entering ipshell.\nHit Ctrl-D to exit') for attr in self.getAttributeDefs(): key = attr['name'] try: value = attr['value'] except: value = '' showLevel(outfile, level + 1) outfile.write('key: %s value: %s\n' % \ (key, value)) for child in self.children: child.show(outfile, level + 1) def annotate(self): self.collect_element_dict() self.annotate_find_type() self.annotate_tree() self.fix_dup_names() self.coerce_attr_types() self.checkMixedBases() def collect_element_dict(self): base = self.getBase() if self.getTopLevel() or len(self.getChildren()) > 0 or \ len(self.getAttributeDefs()) > 0 or base: ElementDict[self.name] = self for child in self.children: child.collect_element_dict() def element_is_complex(self): pass # If it is a mixed-content element and it is defined as # an extension, then all of its bases (base, base of base, ...) # must be mixed-content. Mark it as an error, if not. def checkMixedBases(self): self.checkMixedBasesChain(self, self.mixed) for child in self.children: child.checkMixedBases() def checkMixedBasesChain(self, child, childMixed): base = self.getBase() if base and base in ElementDict: parent = ElementDict[base] if childMixed != parent.isMixed(): self.mixedExtensionError = 1 return parent.checkMixedBasesChain(child, childMixed) def resolve_type(self): self.complex = 0 # If it has any attributes, then it's complex. attrDefs = self.getAttributeDefs() if len(attrDefs) > 0: self.complex = 1 # type_val = '' type_val = self.resolve_type_1() if type_val: if type_val in ElementDict: element = ElementDict[type_val] type_val1 = element.resolve_type_1() if type_val1 in StringType or \ type_val1 == TokenType or \ type_val1 == DateTimeType or \ type_val1 == DateType or \ type_val1 in IntegerType or \ type_val1 == DecimalType or \ type_val1 == PositiveIntegerType or \ type_val1 == NonPositiveIntegerType or \ type_val1 == NegativeIntegerType or \ type_val1 == NonNegativeIntegerType or \ type_val1 == BooleanType or \ type_val1 == FloatType or \ type_val1 == DoubleType: type_val = type_val1 else: self.complex = 1 else: if type_val in StringType or \ type_val == TokenType or \ type_val == DateTimeType or \ type_val == DateType or \ type_val in IntegerType or \ type_val == DecimalType or \ type_val == PositiveIntegerType or \ type_val == NonPositiveIntegerType or \ type_val == NegativeIntegerType or \ type_val == NonNegativeIntegerType or \ type_val == BooleanType or \ type_val == FloatType or \ type_val == DoubleType: pass else: type_val = StringType[0] else: type_val = StringType[0] return type_val def resolve_type_1(self): type_val = '' if 'type' in self.attrs: # fix #type_val = strip_namespace(self.attrs['type']) type_val = self.attrs['type'] elif 'ref' in self.attrs: # fix type_val = strip_namespace(self.attrs['ref']) #type_val = self.attrs['ref'] elif 'name' in self.attrs: # fix type_val = strip_namespace(self.attrs['name']) #type_val = self.attrs['name'] return type_val def annotate_find_type(self): type_val = self.resolve_type() #dbgprint(1, '(aft) n: %s t: %s c: %s id: %s' % \ # (self.name, type_val, self.complex, id(self), )) self.attrs['type'] = type_val self.type = type_val if not self.complex: SimpleElementDict[self.name] = self.name for child in self.children: child.annotate_find_type() def annotate_tree(self): # If there is a namespace, replace it with an underscore. if self.base: self.base = strip_namespace(self.base) self.unmappedCleanName = cleanupName(self.name) self.cleanName = mapName(self.unmappedCleanName) SaxElementDict[self.cleanName] = self self.replace_attributeGroup_names() if 'maxOccurs' in self.attrs.keys(): maxOccurs = self.attrs['maxOccurs'] if maxOccurs == 'unbounded': maxOccurs = 99999 else: try: maxOccurs = int(self.attrs['maxOccurs']) except ValueError: sys.stderr.write('*** %s maxOccurs must be integer or "unbounded".' % \ (self.getName(), ) ) sys.exit(-1) else: maxOccurs = 1 self.maxOccurs = maxOccurs #if self.cleanName == 'Reason_XXX': # ipshell('(annotate_tree) -- Entering ipshell.\\nHit Ctrl-D to exit') # If it does not have a type, then make the type the same as the name. if self.type == 'NoneType' and self.name: self.type = self.name # Is it a mixed-content element definition? if 'mixed' in self.attrs.keys(): mixed = self.attrs['mixed'].strip() if mixed == '1' or mixed.lower() == 'true': self.mixed = 1 # Do it recursively for all descendents. for child in self.children: child.annotate_tree() # # For each name in the attributeGroupNameList for this element, # add the attributes defined for that name in the global # attributeGroup dictionary. def replace_attributeGroup_names(self): for groupName in self.attributeGroupNameList: if groupName in AttributeGroups: attrGroup = AttributeGroups[groupName] for name in attrGroup.getKeys(): attr = attrGroup.get(name) self.attributeDefs[name] = attr else: print '*** Error. attributeGroup %s not defined.' % groupName def __str__(self): s1 = '<"%s" XschemaElement instance at 0x%x>' % \ (self.getName(), id(self)) return s1 def __repr__(self): s1 = '<"%s" XschemaElement instance at 0x%x>' % \ (self.getName(), id(self)) return s1 def fix_dup_names(self): # Patch-up names that are used for both a child element and an attribute. # attrDefs = self.getAttributeDefs() # Collect a list of child element names. # Must do this for base (extension) elements also. elementNames = [] self.collectElementNames(elementNames) replaced = [] # Create the needed new attributes. keys = attrDefs.keys() for key in keys: attr = attrDefs[key] name = attr.getName() if name in elementNames: newName = name + '_attr' newAttr = XschemaAttribute(newName) attrDefs[newName] = newAttr replaced.append(name) # Remove the old (replaced) attributes. for name in replaced: del attrDefs[name] for child in self.children: child.fix_dup_names() def collectElementNames(self, elementNames): for child in self.children: elementNames.append(cleanupName(child.cleanName)) base = self.getBase() if base and base in ElementDict: parent = ElementDict[base] parent.collectElementNames(elementNames) def coerce_attr_types(self): replacements = [] attrDefs = self.getAttributeDefs() for idx, name in enumerate(attrDefs): attr = attrDefs[name] attrType = attr.getData_type() if attrType == IDType or \ attrType == IDREFType or \ attrType == IDREFSType: attr.setData_type(StringType[0]) for child in self.children: child.coerce_attr_types() # end class XschemaElement class XschemaAttributeGroup: def __init__(self, name='', group=None): self.name = name if group: self.group = group else: self.group = {} def setName(self, name): self.name = name def getName(self): return self.name def setGroup(self, group): self.group = group def getGroup(self): return self.group def get(self, name, default=None): if name in self.group: return self.group[name] else: return default def getKeys(self): return self.group.keys() def add(self, name, attr): self.group[name] = attr def delete(self, name): # if has_key(self.group, name): if name in self.group: del self.group[name] return 1 else: return 0 # end class XschemaAttributeGroup class XschemaAttribute: def __init__(self, name, data_type='xs:string', use='optional'): self.name = name self.data_type = data_type self.use = use def setName(self, name): self.name = name def getName(self): return self.name def setData_type(self, data_type): self.data_type = data_type def getData_type(self): return self.data_type def setUse(self, use): self.use = use def getUse(self): return self.use # end class XschemaAttribute # # SAX handler # class XschemaHandler(handler.ContentHandler): def __init__(self): handler.ContentHandler.__init__(self) self.stack = [] self.root = None self.inElement = 0 self.inComplexType = 0 self.inNonanonymousComplexType = 0 self.inSequence = 0 self.inChoice = 1 self.inAttribute = 0 self.inAttributeGroup = 0 self.inSimpleElement = 0 ## self.dbgcount = 1 ## self.dbgnames = [] def getRoot(self): #ipshell('Returning root -- Entering ipshell.\\nHit Ctrl-D to exit') return self.root def showError(self, msg): print msg sys.exit(-1) def startElement(self, name, attrs): # dbgprint(1, 'before schema name: %s SchemaType: %s' % (name, SchemaType,)) if name == SchemaType: # dbgprint(1, '(schema in)') self.inSchema = 1 element = XschemaElement(attrs) if len(self.stack) == 1: element.setTopLevel(1) self.stack.append(element) # If there is an attribute "xmlns" and its value is # "http://www.w3.org/2001/XMLSchema", then remember and # use that namespace prefix. for name, value in attrs.items(): if name[:6] == 'xmlns:' and \ value == 'http://www.w3.org/2001/XMLSchema': nameSpace = name[6:] + ':' set_type_constants(nameSpace) elif name == ElementType or ((name == ComplexTypeType) and (len(self.stack) == 1)): self.inElement = 1 self.inNonanonymousComplexType = 1 element = XschemaElement(attrs) if len(self.stack) == 1: element.setTopLevel(1) if 'substitutionGroup' in attrs.keys()and 'name' in attrs.keys(): substituteName = attrs['name'] headName = attrs['substitutionGroup'] if headName not in SubstitutionGroups: SubstitutionGroups[headName] = [] SubstitutionGroups[headName].append(substituteName) #dbgprint(1, '(startElement) added %s to %s' % (substituteName, headName)) if name == ComplexTypeType: element.complexType = 1 self.stack.append(element) elif name == ComplexTypeType: # If it have any attributes and there is something on the stack, # then copy the attributes to the item on top of the stack. if len(self.stack) > 1 and len(attrs) > 0: parentDict = self.stack[-1].getAttrs() for key in attrs.keys(): parentDict[key] = attrs[key] self.inComplexType = 1 elif name == SequenceType: self.inSequence = 1 elif name == ChoiceType: self.inChoice = 1 elif name == AttributeType: self.inAttribute = 1 if 'name' in attrs.keys(): name = attrs['name'] # fix-attribute-ref elif 'ref' in attrs.keys(): name = strip_namespace(attrs['ref']) else: name = 'no_attribute_name' if 'type' in attrs.keys(): data_type = attrs['type'] else: data_type = StringType[0] if 'use' in attrs.keys(): use = attrs['use'] else: use = 'optional' if self.stack[-1].attributeGroup: # Add this attribute to a current attributeGroup. attribute = XschemaAttribute(name, data_type, use) self.stack[-1].attributeGroup.add(name, attribute) else: # Add this attribute to the element/complexType. attribute = XschemaAttribute(name, data_type, use) self.stack[-1].attributeDefs[name] = attribute elif name == AttributeGroupType: self.inAttributeGroup = 1 # If it has attribute 'name', then it's a definition. # Prepare to save it as an attributeGroup. if 'name' in attrs.keys(): name = strip_namespace(attrs['name']) attributeGroup = XschemaAttributeGroup(name) element = XschemaElement(attrs) if len(self.stack) == 1: element.setTopLevel(1) element.setAttributeGroup(attributeGroup) self.stack.append(element) # If it has attribute 'ref', add it to the list of # attributeGroups for this element/complexType. if 'ref' in attrs.keys(): self.stack[-1].attributeGroupNameList.append(attrs['ref']) elif name == ComplexContentType: pass elif name == ExtensionType: if 'base' in attrs.keys() and len(self.stack) > 0: extensionBase = attrs['base'] if extensionBase in StringType or \ extensionBase == TokenType or \ extensionBase == DateTimeType or \ extensionBase == DateType or \ extensionBase in IntegerType or \ extensionBase == DecimalType or \ extensionBase == PositiveIntegerType or \ extensionBase == NegativeIntegerType or \ extensionBase == NonPositiveIntegerType or \ extensionBase == NonNegativeIntegerType or \ extensionBase == BooleanType or \ extensionBase == FloatType or \ extensionBase == DoubleType: pass else: self.stack[-1].setBase(extensionBase) elif name == AnyAttributeType: # Mark the current element as containing anyAttribute. self.stack[-1].setAnyAttribute(1) def endElement(self, name): if self.inSimpleElement: self.inSimpleElement = 0 elif name == ElementType or (name == ComplexTypeType and self.stack[-1].complexType): self.inElement = 0 self.inNonanonymousComplexType = 0 element = self.stack.pop() self.stack[-1].addChild(element) elif name == ComplexTypeType: self.inComplexType = 0 elif name == SequenceType: self.inSequence = 0 elif name == ChoiceType: self.inChoice = 0 elif name == AttributeType: self.inAttribute = 0 elif name == AttributeGroupType: self.inAttributeGroup = 0 if self.stack[-1].attributeGroup: # The top of the stack contains an XschemaElement which # contains the definition of an attributeGroup. # Save this attributeGroup in the # global AttributeGroup dictionary. attributeGroup = self.stack[-1].attributeGroup name = attributeGroup.getName() AttributeGroups[name] = attributeGroup self.stack[-1].attributeGroup = None self.stack.pop() else: # This is a reference to an attributeGroup. # We have already added it to the list of attributeGroup names. # Leave it. We'll fill it in during annotate. pass elif name == SchemaType: self.inSchema = 0 if len(self.stack) != 1: print '*** error stack. len(self.stack): %d' % len(self.stack) sys.exit(-1) self.root = self.stack[0] elif name == ComplexContentType: pass elif name == ExtensionType: pass def characters(self, chrs): if self.inElement: pass elif self.inComplexType: pass elif self.inSequence: pass elif self.inChoice: pass # # Code generation # def generateExportFn_1(outfile, child, name, fill): cleanName = cleanupName(name) if child.getType() in StringType or \ child.getType() == TokenType or \ child.getType() == DateTimeType or \ child.getType() == DateType: s1 = '%s showIndent(outfile, level)\n' % fill outfile.write(s1) s1 = "%s outfile.write('<%s>%%s\\n' %% quote_xml(self.get%s()))\n" % \ (fill, name, name, cleanName.capitalize()) outfile.write(s1) elif child.getType() in IntegerType or \ child.getType() == BooleanType or \ child.getType() == PositiveIntegerType or \ child.getType() == NonPositiveIntegerType or \ child.getType() == NegativeIntegerType or \ child.getType() == NonNegativeIntegerType: s1 = '%s showIndent(outfile, level)\n' % fill outfile.write(s1) s1 = "%s outfile.write('<%s>%%d\\n' %% self.get%s())\n" % \ (fill, name, name, cleanName.capitalize()) outfile.write(s1) elif child.getType() == FloatType or \ child.getType() == DecimalType: s1 = '%s showIndent(outfile, level)\n' % fill outfile.write(s1) s1 = "%s outfile.write('<%s>%%f\\n' %% self.get%s())\n" % \ (fill, name, name, cleanName.capitalize()) outfile.write(s1) elif child.getType() == DoubleType: s1 = '%s showIndent(outfile, level)\n' % fill outfile.write(s1) s1 = "%s outfile.write('<%s>%%e\\n' %% self.get%s())\n" % \ (fill, name, name, cleanName.capitalize()) outfile.write(s1) else: s1 = "%s if self.%s:\n" % (fill, cleanName) outfile.write(s1) if name == child.getType(): s1 = "%s self.%s.export(outfile, level)\n" % \ (fill, cleanName) else: s1 = "%s self.%s.export(outfile, level, name_='%s')\n" % \ (fill, cleanName, name) outfile.write(s1) def generateExportFn_2(outfile, child, name, fill): cleanName = cleanupName(name) s1 = "%s for %s_ in self.get%s():\n" % (fill, cleanName, cleanName.capitalize()) outfile.write(s1) if child.getType() in StringType or \ child.getType() == TokenType or \ child.getType() == DateTimeType or \ child.getType() == DateType: s1 = '%s showIndent(outfile, level)\n' % fill outfile.write(s1) s1 = "%s outfile.write('<%s>%%s\\n' %% quote_xml(%s_))\n" % \ (fill, name, name, cleanName,) outfile.write(s1) elif child.getType() in IntegerType or \ child.getType() == BooleanType or \ child.getType() == PositiveIntegerType or \ child.getType() == NonPositiveIntegerType or \ child.getType() == NegativeIntegerType or \ child.getType() == NonNegativeIntegerType: s1 = '%s showIndent(outfile, level)\n' % fill outfile.write(s1) s1 = "%s outfile.write('<%s>%%d\\n' %% %s_)\n" % \ (fill, name, name, cleanName, ) outfile.write(s1) elif child.getType() == FloatType or \ child.getType() == DecimalType: s1 = '%s showIndent(outfile, level)\n' % fill outfile.write(s1) s1 = "%s outfile.write('<%s>%%f\\n' %% %s_)\n" % \ (fill, name, name, cleanName, ) outfile.write(s1) elif child.getType() == DoubleType: s1 = '%s showIndent(outfile, level)\n' % fill outfile.write(s1) s1 = "%s outfile.write('<%s>%%e\\n' %% %s_)\n" % \ (fill, name, name, cleanName) outfile.write(s1) else: if name == child.getType(): s1 = "%s %s_.export(outfile, level)\n" % (fill, cleanName) else: s1 = "%s %s_.export(outfile, level, name_='%s')\n" % \ (fill, cleanName, cleanName, ) outfile.write(s1) def generateExportAttributes(outfile, element, hasAttributes): if len(element.getAttributeDefs()) > 0: hasAttributes += 1 attrDefs = element.getAttributeDefs() for key in attrDefs.keys(): attrDef = attrDefs[key] name = attrDef.getName() cleanName = cleanupName(name) capName = cleanName.capitalize() if attrDef.getUse() == 'optional': s1 = " if self.get%s() is not None:\n" % (capName, ) outfile.write(s1) s1 = " outfile.write(' %s=\"%%s\"' %% (self.get%s(), ))\n" % \ (name, capName, ) outfile.write(s1) else: s1 = " outfile.write(' %s=\"%%s\"' %% (self.get%s(), ))\n" % \ (name, capName, ) outfile.write(s1) if element.getAnyAttribute(): s1 = ' for name, value in self.anyAttributes_.items():\n' outfile.write(s1) s1 = " outfile.write(' %s=\"%s\"' % (name, value, ))\n" outfile.write(s1) return hasAttributes def generateExportChildren(outfile, element, hasChildren): if len(element.getChildren()) > 0: hasChildren += 1 if element.isMixed(): s1 = " for item_ in self.content_:\n" outfile.write(s1) s1 = " item_.export(outfile, level, name_)\n" outfile.write(s1) else: for child in element.getChildren(): name = child.getName() if child.getMaxOccurs() > 1: generateExportFn_2(outfile, child, name, ' ') else: generateExportFn_1(outfile, child, name, '') ## base = element.getBase() ## if base and base in ElementDict: ## parent = ElementDict[base] ## hasAttributes = generateExportChildren(outfile, parent, hasChildren) return hasChildren def countChildren(element, count): count += len(element.getChildren()) base = element.getBase() if base and base in ElementDict: parent = ElementDict[base] count = countChildren(parent, count) return count def generateExportFn(outfile, prefix, element): base = element.getBase() s1 = " def export(self, outfile, level, name_='%s'):\n" % \ element.getName() outfile.write(s1) s1 = ' showIndent(outfile, level)\n' outfile.write(s1) if len(element.getAttributeDefs()) > 0: s1 = " outfile.write('<%s' % (name_, ))\n" outfile.write(s1) s1 = " self.exportAttributes(outfile, level, name_='%s')\n" % \ element.getName() outfile.write(s1) if element.isMixed(): s1 = " outfile.write('>')\n" else: s1 = " outfile.write('>\\n')\n" outfile.write(s1) else: if element.isMixed(): s1 = " outfile.write('<%s>' % name_)\n" else: s1 = " outfile.write('<%s>\\n' % name_)\n" outfile.write(s1) s1 = " self.exportChildren(outfile, level + 1, name_)\n" outfile.write(s1) s1 = ' showIndent(outfile, level)\n' outfile.write(s1) s1 = " outfile.write('\\n' % name_)\n" outfile.write(s1) s1 = " def exportAttributes(self, outfile, level, name_='%s'):\n" % \ element.getName() outfile.write(s1) hasAttributes = 0 hasAttributes = generateExportAttributes(outfile, element, hasAttributes) if base: hasAttributes += 1 s1 = " %s.exportAttributes(self, outfile, level, name_='%s')\n" % \ (base, element.getName(), ) outfile.write(s1) if hasAttributes == 0: s1 = " pass\n" outfile.write(s1) ## if len(element.getChildren()) > 0 and not element.isMixed(): ## s1 = ' showIndent(outfile, level)\n' ## outfile.write(s1) s1 = " def exportChildren(self, outfile, level, name_='%s'):\n" % \ element.getName() outfile.write(s1) hasChildren = 0 hasChildren = generateExportChildren(outfile, element, hasChildren) if base: hasChildren += 1 s1 = " %s.exportChildren(self, outfile, level, name_)\n" % (base, ) outfile.write(s1) count = countChildren(element, 0) if count == 0: s1 = " outfile.write(self.valueOf_)\n" outfile.write(s1) # # Generate exportLiteral method. # def generateExportLiteralFn_1(outfile, child, name, fill): mappedName = mapName(name) if child.getType() in StringType or \ child.getType() == TokenType or \ child.getType() == DateTimeType or \ child.getType() == DateType: s1 = '%s showIndent(outfile, level)\n' % fill outfile.write(s1) s1 = "%s outfile.write('%s=%%s,\\n' %% quote_python(self.get%s()))\n" % \ (fill, mappedName, name.capitalize()) outfile.write(s1) elif child.getType() in IntegerType or \ child.getType() == BooleanType or \ child.getType() == PositiveIntegerType or \ child.getType() == NonPositiveIntegerType or \ child.getType() == NegativeIntegerType or \ child.getType() == NonNegativeIntegerType: s1 = '%s showIndent(outfile, level)\n' % fill outfile.write(s1) s1 = "%s outfile.write('%s=%%d,\\n' %% self.get%s())\n" % \ (fill, mappedName, name.capitalize()) outfile.write(s1) elif child.getType() == FloatType or \ child.getType() == DecimalType: s1 = '%s showIndent(outfile, level)\n' % fill outfile.write(s1) s1 = "%s outfile.write('%s=%%f,\\n' %% self.get%s())\n" % \ (fill, mappedName, name.capitalize()) outfile.write(s1) elif child.getType() == DoubleType: s1 = '%s showIndent(outfile, level)\n' % fill outfile.write(s1) s1 = "%s outfile.write('%s=%%e,\\n' %% self.get%s())\n" % \ (fill, name, name.capitalize()) outfile.write(s1) else: s1 = "%s if self.%s:\n" % (fill, name) outfile.write(s1) s1 = '%s showIndent(outfile, level)\n' % fill outfile.write(s1) s1 = "%s outfile.write('%s=%s(\\n')\n" % \ (fill, name, child.getType()) outfile.write(s1) if name == child.getType(): s1 = "%s self.%s.exportLiteral(outfile, level)\n" % \ (fill, name) else: s1 = "%s self.%s.exportLiteral(outfile, level, name_='%s')\n" % \ (fill, name, name) outfile.write(s1) s1 = '%s showIndent(outfile, level)\n' % fill outfile.write(s1) s1 = "%s outfile.write('),\\n')\n" % (fill, ) outfile.write(s1) def generateExportLiteralFn_2(outfile, child, name, fill): if child.getType() in StringType or \ child.getType() == TokenType or \ child.getType() == DateTimeType or \ child.getType() == DateType: s1 = '%s showIndent(outfile, level)\n' % fill outfile.write(s1) s1 = "%s outfile.write('%%s,\\n' %% quote_python(%s))\n" % \ (fill, name) outfile.write(s1) elif child.getType() in IntegerType or \ child.getType() == BooleanType or \ child.getType() == PositiveIntegerType or \ child.getType() == NonPositiveIntegerType or \ child.getType() == NegativeIntegerType or \ child.getType() == NonNegativeIntegerType: s1 = '%s showIndent(outfile, level)\n' % fill outfile.write(s1) s1 = "%s outfile.write('%%d,\\n' %% %s)\n" % \ (fill, name) outfile.write(s1) elif child.getType() == FloatType or \ child.getType() == DecimalType: s1 = '%s showIndent(outfile, level)\n' % fill outfile.write(s1) s1 = "%s outfile.write('%%f,\\n' %% %s)\n" % \ (fill, name) outfile.write(s1) elif child.getType() == DoubleType: s1 = '%s showIndent(outfile, level)\n' % fill outfile.write(s1) s1 = "%s outfile.write('%%e,\\n' %% %s)\n" % \ (fill, name) outfile.write(s1) else: s1 = '%s showIndent(outfile, level)\n' % fill outfile.write(s1) s1 = "%s outfile.write('%s(\\n')\n" % \ (fill, cleanupName(child.getType())) outfile.write(s1) if name == child.getType(): s1 = "%s %s.exportLiteral(outfile, level)\n" % (fill, child.getType()) else: s1 = "%s %s.exportLiteral(outfile, level, name_='%s')\n" % \ (fill, name, name) outfile.write(s1) s1 = '%s showIndent(outfile, level)\n' % fill outfile.write(s1) s1 = "%s outfile.write('),\\n')\n" % (fill, ) outfile.write(s1) def generateExportLiteralFn(outfile, prefix, element): base = element.getBase() s1 = " def exportLiteral(self, outfile, level, name_='%s'):\n" % element.getName() outfile.write(s1) s1 = " level += 1\n" outfile.write(s1) s1 = " self.exportLiteralAttributes(outfile, level, name_)\n" outfile.write(s1) s1 = " self.exportLiteralChildren(outfile, level, name_)\n" outfile.write(s1) s1 = " def exportLiteralAttributes(self, outfile, level, name_):\n" outfile.write(s1) count = 0 attrDefs = element.getAttributeDefs() for key in attrDefs: attrDef = attrDefs[key] count += 1 name = attrDef.getName() cleanName = cleanupName(name) capName = cleanName.capitalize() mappedName = mapName(cleanName) s1 = " showIndent(outfile, level)\n" outfile.write(s1) ## ipshell('(generateExportLiteral) -- Entering ipshell.\\nHit Ctrl-D to exit') stringType = 0 data_type = attrDef.getData_type() if data_type.find('string') >= 0: stringType = 1 else: stringType = 1 if stringType: s1 = " outfile.write('%s = \"%%s\",\\n' %% (self.get%s(),))\n" % \ (mappedName, capName,) else: s1 = " outfile.write('%s = %%s,\\n' %% (self.get%s(),))\n" % \ (mappedName, capName,) outfile.write(s1) if element.getAnyAttribute(): count += 1 s1 = ' for name, value in self.anyAttributes_.items():\n' outfile.write(s1) s1 = ' showIndent(outfile, level)\n' outfile.write(s1) s1 = " outfile.write('%s = \"%s\",\\n' % (name, value,))\n" outfile.write(s1) if count == 0: s1 = " pass\n" outfile.write(s1) if base: s1 = " %s.exportLiteralAttributes(self, outfile, level, name_)\n" % \ (base, ) outfile.write(s1) s1 = " def exportLiteralChildren(self, outfile, level, name_):\n" outfile.write(s1) for child in element.getChildren(): name = child.getName() name = cleanupName(name) #unmappedName = child.getUnmappedCleanName() #cleanName = cleanupName(name) #mappedName = mapName(cleanName) if element.isMixed(): s1 = " showIndent(outfile, level)\n" outfile.write(s1) s1 = " outfile.write('content_ = [\\n')\n" outfile.write(s1) s1 = ' for item_ in self.content_:\n' outfile.write(s1) s1 = ' item_.exportLiteral(outfile, level, name_)\n' outfile.write(s1) s1 = " showIndent(outfile, level)\n" outfile.write(s1) s1 = " outfile.write('],\\n')\n" outfile.write(s1) else: if child.getMaxOccurs() > 1: s1 = " showIndent(outfile, level)\n" outfile.write(s1) s1 = " outfile.write('%s=[\\n')\n" % name outfile.write(s1) s1 = " level += 1\n" outfile.write(s1) s1 = " for %s in self.%s:\n" % (name, name) outfile.write(s1) generateExportLiteralFn_2(outfile, child, name, ' ') s1 = " level -= 1\n" outfile.write(s1) s1 = " showIndent(outfile, level)\n" outfile.write(s1) s1 = " outfile.write('],\\n')\n" outfile.write(s1) else: generateExportLiteralFn_1(outfile, child, name, '') if len(element.getChildren()) == 0: s1 = " showIndent(outfile, level)\n" outfile.write(s1) s1 = " outfile.write('valueOf_ = \"%s\",\\n' % (self.valueOf_,))\n" outfile.write(s1) if base: s1 = " %s.exportLiteralChildren(self, outfile, level, name_)\n" % \ (base, ) outfile.write(s1) #s1 = " level -= 1\n" #outfile.write(s1) # # Generate build method. # def generateBuildAttributes(outfile, element, hasAttributes): attrDefs = element.getAttributeDefs() for key in attrDefs: attrDef = attrDefs[key] hasAttributes += 1 name = attrDef.getName() cleanName = cleanupName(name) mappedName = mapName(cleanName) atype = attrDef.getData_type() if atype in IntegerType or \ atype == PositiveIntegerType or \ atype == NonPositiveIntegerType or \ atype == NegativeIntegerType or \ atype == NonNegativeIntegerType: s1 = " if attrs.get('%s'):\n" % name outfile.write(s1) s1 = ' try:\n' outfile.write(s1) s1 = " self.%s = int(attrs.get('%s').value)\n" % \ (mappedName, name) outfile.write(s1) s1 = ' except ValueError:\n' outfile.write(s1) s1 = " raise ValueError('Bad integer attribute (%s)')\n" % \ (name, ) outfile.write(s1) if atype == PositiveIntegerType: s1 = ' if self.%s <= 0:\n' % mappedName outfile.write(s1) s1 = " raise ValueError('Invalid PositiveInteger (%s)')\n" % name outfile.write(s1) elif atype == NonPositiveIntegerType: s1 = ' if self.%s > 0:\n' % mappedName outfile.write(s1) s1 = " raise ValueError('Invalid NonPositiveInteger (%s)')\n" % name outfile.write(s1) elif atype == NegativeIntegerType: s1 = ' if self.%s >= 0:\n' % mappedName outfile.write(s1) s1 = " raise ValueError('Invalid NegativeInteger (%s)')\n" % name outfile.write(s1) elif atype == NonNegativeIntegerType: s1 = ' if self.%s < 0:\n' % mappedName outfile.write(s1) s1 = " raise ValueError('Invalid NonNegativeInteger (%s)')\n" % name outfile.write(s1) elif atype == BooleanType: s1 = " if attrs.get('%s'):\n" % (name, ) outfile.write(s1) s1 = " if attrs.get('%s').value in ('true', '1'):\n" % \ (name, ) outfile.write(s1) s1 = " self.%s = 1\n" % (mappedName, ) outfile.write(s1) s1 = " elif attrs.get('%s').value in ('false', '0'):\n" % \ (name, ) outfile.write(s1) s1 = " self.%s = 0\n" % (mappedName, ) outfile.write(s1) s1 = ' else:\n' outfile.write(s1) s1 = " raise ValueError('Bad boolean attribute (%s)')\n" % \ (name, ) outfile.write(s1) elif atype == FloatType or atype == DoubleType or atype == DecimalType: s1 = " if attrs.get('%s'):\n" % (name, ) outfile.write(s1) s1 = ' try:\n' outfile.write(s1) s1 = " self.%s = float(attrs.get('%s').value)\n" % \ (mappedName, name, ) outfile.write(s1) s1 = ' except:\n' outfile.write(s1) s1 = " raise ValueError('Bad float/double attribute (%s)')\n" % \ (name, ) outfile.write(s1) elif atype == TokenType: s1 = " if attrs.get('%s'):\n" % (name, ) outfile.write(s1) s1 = " self.%s = attrs.get('%s').value\n" % \ (mappedName, name, ) outfile.write(s1) s1 = " self.%s = ' '.join(self.%s.split())\n" % \ (mappedName, mappedName, ) outfile.write(s1) else: # Assume attr['type'] in StringType or attr['type'] == DateTimeType: s1 = " if attrs.get('%s'):\n" % (name, ) outfile.write(s1) s1 = " self.%s = attrs.get('%s').value\n" % \ (mappedName, name, ) outfile.write(s1) if element.getAnyAttribute(): s1 = ' self.anyAttributes_ = {}\n' outfile.write(s1) s1 = ' for name, value in attrs.items():\n' outfile.write(s1) s1List = [' if'] firstTime = 1 for key in attrDefs: if firstTime: s1List.append(' name != "%s"' % key) firstTime = 0 else: s1List.append(' and name != "%s"' % key) s1List.append(':\n') s1 = ''.join(s1List) outfile.write(s1) s1 = ' self.anyAttributes_[name] = value\n' outfile.write(s1) return hasAttributes def generateBuildMixed_1(outfile, prefix, child, headChild, keyword, delayed): global DelayedElements, DelayedElements_subclass nestedElements = 1 origName = child.getName() name = child.getCleanName() headName = cleanupName(headChild.getName()) childType = child.getType() if childType in StringType or \ childType == TokenType or \ childType == DateTimeType or \ childType == DateType: s1 = ' %s child_.nodeType == Node.ELEMENT_NODE and \\\n' % \ keyword outfile.write(s1) s1 = " nodeName_ == '%s':\n" % origName outfile.write(s1) s1 = " value_ = []\n" outfile.write(s1) s1 = " for text_ in child_.childNodes:\n" outfile.write(s1) s1 = " value_.append(text_.nodeValue)\n" outfile.write(s1) s1 = " valuestr_ = ''.join(value_)\n" outfile.write(s1) if childType == TokenType: s1 = " valuestr_ = ' '.join(valuestr_.split())\n" outfile.write(s1) s1 = " obj_ = self.mixedclass_(MixedContainer.CategorySimple,\n" outfile.write(s1) s1 = " MixedContainer.TypeString, '%s', valuestr_)\n" % \ origName outfile.write(s1) s1 = " self.content_.append(obj_)\n" outfile.write(s1) elif childType in IntegerType or \ childType == PositiveIntegerType or \ childType == NonPositiveIntegerType or \ childType == NegativeIntegerType or \ childType == NonNegativeIntegerType: s1 = " %s child_.nodeType == Node.ELEMENT_NODE and \\\n" % \ keyword outfile.write(s1) s1 = " nodeName_ == '%s':\n" % origName outfile.write(s1) s1 = " if child_.firstChild:\n" outfile.write(s1) s1 = " sval_ = child_.firstChild.nodeValue\n" outfile.write(s1) s1 = " try:\n" outfile.write(s1) s1 = " ival_ = int(sval_)\n" outfile.write(s1) s1 = " except ValueError:\n" outfile.write(s1) s1 = " raise ValueError('requires integer -- %s' % child_.toxml())\n" outfile.write(s1) if childType == PositiveIntegerType: s1 = " if ival_ <= 0:\n" outfile.write(s1) s1 = " raise ValueError('Invalid positiveInteger (%s)' % child_.toxml()))\n" outfile.write(s1) if childType == NonPositiveIntegerType: s1 = " if ival_ > 0:\n" outfile.write(s1) s1 = " raise ValueError('Invalid nonPositiveInteger (%s)' % child_.toxml()))\n" outfile.write(s1) if childType == NegativeIntegerType: s1 = " if ival_ >= 0:\n" outfile.write(s1) s1 = " raise ValueError('Invalid negativeInteger (%s)' % child_.toxml()))\n" outfile.write(s1) if childType == NonNegativeIntegerType: s1 = " if ival_ < 0:\n" outfile.write(s1) s1 = " raise ValueError('Invalid nonNegativeInteger (%s)' % child_.toxml()))\n" outfile.write(s1) s1 = " else:\n" outfile.write(s1) s1 = " ival_ = -1\n" outfile.write(s1) s1 = " obj_ = self.mixedclass_(MixedContainer.CategorySimple,\n" outfile.write(s1) s1 = " MixedContainer.TypeInteger, '%s', ival_)\n" % \ origName outfile.write(s1) s1 = " self.content_.append(obj_)\n" outfile.write(s1) elif childType == BooleanType: s1 = " %s child_.nodeType == Node.ELEMENT_NODE and \\\n" % \ keyword outfile.write(s1) s1 = " nodeName_ == '%s':\n" % origName outfile.write(s1) s1 = " if child_.firstChild:\n" outfile.write(s1) s1 = " sval_ = child_.firstChild.nodeValue\n" outfile.write(s1) s1 = " if sval_ in ('true', '1'):\n" outfile.write(s1) s1 = " ival_ = 1\n" outfile.write(s1) s1 = " elif sval_ in ('false', '0'):\n" outfile.write(s1) s1 = " ival_ = 0\n" outfile.write(s1) s1 = " else:\n" outfile.write(s1) s1 = " raise ValueError('requires boolean -- %s' % child_.toxml())\n" outfile.write(s1) s1 = " obj_ = self.mixedclass_(MixedContainer.CategorySimple,\n" outfile.write(s1) s1 = " MixedContainer.TypeInteger, '%s', ival_)\n" % \ origName outfile.write(s1) s1 = " self.content_.append(obj_)\n" outfile.write(s1) elif childType == FloatType or \ childType == DoubleType or \ childType == DecimalType: s1 = " %s child_.nodeType == Node.ELEMENT_NODE and \\\n" % \ keyword outfile.write(s1) s1 = " nodeName_ == '%s':\n" % origName outfile.write(s1) s1 = " if child_.firstChild:\n" outfile.write(s1) s1 = " sval_ = child_.firstChild.nodeValue\n" outfile.write(s1) s1 = " try:\n" outfile.write(s1) s1 = " fval_ = float(sval_)\n" outfile.write(s1) s1 = " except ValueError:\n" outfile.write(s1) s1 = " raise ValueError('requires float (or double) -- %s' % child_.toxml())\n" outfile.write(s1) s1 = " obj_ = self.mixedclass_(MixedContainer.CategorySimple,\n" outfile.write(s1) s1 = " MixedContainer.TypeFloat, '%s', fval_)\n" % \ origName outfile.write(s1) s1 = " self.content_.append(obj_)\n" outfile.write(s1) else: # Perhaps it's a complexType that is defined right here. # Generate (later) a class for the nested types. if not delayed and not child in DelayedElements: DelayedElements.append(child) DelayedElements_subclass.append(child) s1 = " %s child_.nodeType == Node.ELEMENT_NODE and \\\n" % \ keyword outfile.write(s1) s1 = " nodeName_ == '%s':\n" % origName outfile.write(s1) s1 = " childobj_ = %s%s.factory()\n" % \ (prefix, cleanupName(mapName(childType))) outfile.write(s1) s1 = " childobj_.build(child_)\n" outfile.write(s1) s1 = " obj_ = self.mixedclass_(MixedContainer.CategoryComplex,\n" outfile.write(s1) s1 = " MixedContainer.TypeNone, '%s', childobj_)\n" % \ origName outfile.write(s1) s1 = " self.content_.append(obj_)\n" outfile.write(s1) def generateBuildMixed(outfile, prefix, element, keyword, delayed, hasChildren): for child in element.getChildren(): generateBuildMixed_1(outfile, prefix, child, child, keyword, delayed) hasChildren += 1 keyword = 'elif' # Does this element have a substitutionGroup? # If so generate a clause for each element in the substitutionGroup. if child.getName() in SubstitutionGroups: for memberName in SubstitutionGroups[child.getName()]: if memberName in ElementDict: member = ElementDict[memberName] generateBuildMixed_1(outfile, prefix, member, child, keyword, delayed) s1 = " %s child_.nodeType == Node.TEXT_NODE:\n" % keyword outfile.write(s1) s1 = " obj_ = self.mixedclass_(MixedContainer.CategoryText,\n" outfile.write(s1) s1 = " MixedContainer.TypeNone, '', child_.nodeValue)\n" outfile.write(s1) s1 = " self.content_.append(obj_)\n" outfile.write(s1) ## base = element.getBase() ## if base and base in ElementDict: ## parent = ElementDict[base] ## hasChildren = generateBuildMixed(outfile, prefix, parent, keyword, delayed, hasChildren) return hasChildren def generateBuildStandard_1(outfile, prefix, child, headChild, keyword, delayed): global DelayedElements, DelayedElements_subclass origName = child.getName() name = cleanupName(child.getName()) mappedName = mapName(name) headName = cleanupName(headChild.getName()) attrCount = len(child.getAttributeDefs()) #dbgprint(1, '(gbs) name: %s type: %s complex: %s id: %s' % \ # (child.getName(), child.getType(), child.isComplex(), id(child), )) childType = child.getType() if attrCount == 0 and \ (childType in StringType or \ childType == TokenType or \ childType == DateTimeType or \ childType == DateType \ ): s1 = ' %s child_.nodeType == Node.ELEMENT_NODE and \\\n' % \ keyword outfile.write(s1) s1 = " nodeName_ == '%s':\n" % origName outfile.write(s1) s1 = " %s_ = ''\n" % name outfile.write(s1) s1 = " for text__content_ in child_.childNodes:\n" outfile.write(s1) s1 = " %s_ += text__content_.nodeValue\n" % name outfile.write(s1) if childType == TokenType: s1 = " %s_ = ' '.join(%s_.split())\n" % (name, name, ) outfile.write(s1) if child.getMaxOccurs() > 1: s1 = " self.%s.append(%s_)\n" % (mappedName, name, ) outfile.write(s1) else: s1 = " self.%s = %s_\n" % (mappedName, name, ) outfile.write(s1) elif childType in IntegerType or \ childType == PositiveIntegerType or \ childType == NonPositiveIntegerType or \ childType == NegativeIntegerType or \ childType == NonNegativeIntegerType: s1 = " %s child_.nodeType == Node.ELEMENT_NODE and \\\n" % \ keyword outfile.write(s1) s1 = " nodeName_ == '%s':\n" % origName outfile.write(s1) s1 = " if child_.firstChild:\n" outfile.write(s1) s1 = " sval_ = child_.firstChild.nodeValue\n" outfile.write(s1) s1 = " try:\n" outfile.write(s1) s1 = " ival_ = int(sval_)\n" outfile.write(s1) s1 = " except ValueError:\n" outfile.write(s1) s1 = " raise ValueError('requires integer -- %s' % child_.toxml())\n" outfile.write(s1) if childType == PositiveIntegerType: s1 = " if ival_ <= 0:\n" outfile.write(s1) s1 = " raise ValueError('requires positiveInteger -- %s' % child_.toxml())\n" outfile.write(s1) elif childType == NonPositiveIntegerType: s1 = " if ival_ > 0:\n" outfile.write(s1) s1 = " raise ValueError('requires nonPositiveInteger -- %s' % child_.toxml())\n" outfile.write(s1) elif childType == NegativeIntegerType: s1 = " if ival_ >= 0:\n" outfile.write(s1) s1 = " raise ValueError('requires negativeInteger -- %s' % child_.toxml())\n" outfile.write(s1) elif childType == NonNegativeIntegerType: s1 = " if ival_ < 0:\n" outfile.write(s1) s1 = " raise ValueError('requires nonNegativeInteger -- %s' % child_.toxml())\n" outfile.write(s1) if child.getMaxOccurs() > 1: s1 = " self.%s.append(ival_)\n" % (mappedName, ) outfile.write(s1) else: s1 = " self.%s = ival_\n" % (mappedName, ) outfile.write(s1) elif childType == BooleanType: s1 = " %s child_.nodeType == Node.ELEMENT_NODE and \\\n" % \ keyword outfile.write(s1) s1 = " nodeName_ == '%s':\n" % origName outfile.write(s1) s1 = " if child_.firstChild:\n" outfile.write(s1) s1 = " sval_ = child_.firstChild.nodeValue\n" outfile.write(s1) s1 = " if sval_ in ('true', '1'):\n" outfile.write(s1) s1 = " ival_ = 1\n" outfile.write(s1) s1 = " elif sval_ in ('false', '0'):\n" outfile.write(s1) s1 = " ival_ = 0\n" outfile.write(s1) s1 = " else:\n" outfile.write(s1) s1 = " raise ValueError('requires boolean -- %s' % child_.toxml())\n" outfile.write(s1) if child.getMaxOccurs() > 1: s1 = " self.%s.append(ival_)\n" % (mappedName, ) outfile.write(s1) else: s1 = " self.%s = ival_\n" % (mappedName, ) outfile.write(s1) elif childType == FloatType or \ childType == DoubleType or \ childType == DecimalType: s1 = " %s child_.nodeType == Node.ELEMENT_NODE and \\\n" % \ keyword outfile.write(s1) s1 = " nodeName_ == '%s':\n" % origName outfile.write(s1) s1 = " if child_.firstChild:\n" outfile.write(s1) s1 = " sval_ = child_.firstChild.nodeValue\n" outfile.write(s1) s1 = " try:\n" outfile.write(s1) s1 = " fval_ = float(sval_)\n" outfile.write(s1) s1 = " except ValueError:\n" outfile.write(s1) s1 = " raise ValueError('requires float (or double) -- %s' % child_.toxml())\n" outfile.write(s1) if child.getMaxOccurs() > 1: s1 = " self.%s.append(fval_)\n" % (mappedName, ) outfile.write(s1) else: s1 = " self.%s = fval_\n" % (mappedName, ) outfile.write(s1) else: # Perhaps it's a complexType that is defined right here. # Generate (later) a class for the nested types. if not delayed and not child in DelayedElements: DelayedElements.append(child) DelayedElements_subclass.append(child) s1 = " %s child_.nodeType == Node.ELEMENT_NODE and \\\n" % \ keyword outfile.write(s1) s1 = " nodeName_ == '%s':\n" % origName outfile.write(s1) s1 = " obj_ = %s%s.factory()\n" % \ (prefix, cleanupName(mapName(childType))) outfile.write(s1) s1 = " obj_.build(child_)\n" outfile.write(s1) if headChild.getMaxOccurs() > 1: s1 = " self.%s.append(obj_)\n" % headName outfile.write(s1) else: s1 = " self.set%s(obj_)\n" % headName.capitalize() outfile.write(s1) def generateBuildStandard(outfile, prefix, element, keyword, delayed, hasChildren): for child in element.getChildren(): #dbgprint(1, '(generateBuildStandard) %s type: %s' % (child.getName(), child.getType(),)) generateBuildStandard_1(outfile, prefix, child, child, keyword, delayed) hasChildren += 1 keyword = 'elif' # Does this element have a substitutionGroup? # If so generate a clause for each element in the substitutionGroup. childName = child.getName() if childName in SubstitutionGroups: #dbgprint(1, '(BldStd) found: %s in %s' % (childName, SubstitutionGroups)) for memberName in SubstitutionGroups[childName]: memberName = cleanupName(memberName) if memberName in ElementDict: member = ElementDict[memberName] #dbgprint(1, '(BldStd) found subst: %s/%s' % (memberName, member)) generateBuildStandard_1(outfile, prefix, member, child, keyword, delayed) return hasChildren def generateBuildFn(outfile, prefix, element, delayed): base = element.getBase() outfile.write(' def build(self, node_):\n') outfile.write(' attrs = node_.attributes\n') outfile.write(' self.buildAttributes(attrs)\n') ## if len(element.getChildren()) > 0: outfile.write(' for child_ in node_.childNodes:\n') outfile.write(" nodeName_ = child_.nodeName.split(':')[-1]\n") outfile.write(" self.buildChildren(child_, nodeName_)\n") outfile.write(' def buildAttributes(self, attrs):\n') hasAttributes = generateBuildAttributes(outfile, element, 0) if base: hasAttributes += 1 s1 = ' %s.buildAttributes(self, attrs)\n' % (base, ) outfile.write(s1) if hasAttributes == 0: outfile.write(' pass\n') outfile.write(' def buildChildren(self, child_, nodeName_):\n') keyword = 'if' hasChildren = 0 if element.isMixed(): hasChildren = generateBuildMixed(outfile, prefix, element, keyword, delayed, hasChildren) else: # not element.isMixed() hasChildren = generateBuildStandard(outfile, prefix, element, keyword, delayed, hasChildren) if hasChildren == 0: s1 = " self.valueOf_ = ''\n" outfile.write(s1) s1 = " for child in child_.childNodes:\n" outfile.write(s1) s1 = " if child.nodeType == Node.TEXT_NODE:\n" outfile.write(s1) s1 = " self.valueOf_ += child.nodeValue\n" outfile.write(s1) if base and base in ElementDict: parent = ElementDict[base] if len(parent.getChildren()) > 0: s1 = " %s.buildChildren(self, child_, nodeName_)\n" % (base, ) outfile.write(s1) def countElementChildren(element, count): count += len(element.getChildren()) base = element.getBase() if base and base in ElementDict: parent = ElementDict[base] countElementChildren(parent, count) return count def buildCtorArgs_multilevel(element): content = [] add = content.append buildCtorArgs_multilevel_aux(add, element) count = countElementChildren(element, 0) if count == 0: add(", valueOf_=''") if element.isMixed(): add(', mixedclass_=None') add(', content_=None') s1 = ''.join(content) return s1 def buildCtorArgs_multilevel_aux(add, element): buildCtorArgs_aux(add, element) base = element.getBase() if base and base in ElementDict: parent = ElementDict[base] buildCtorArgs_multilevel_aux(add, parent) def buildCtorArgs_1_level(element): content = [] add = content.append buildCtorArgs_aux(add, element) count = countElementChildren(element, 0) if count == 0: add(", valueOf_=''") s1 = ''.join(content) return s1 def buildCtorArgs_aux(add, element): attrDefs = element.getAttributeDefs() for key in attrDefs: attrDef = attrDefs[key] name = attrDef.getName() mappedName = name.replace(':', '_') mappedName = cleanupName(mapName(mappedName)) try: atype = attrDef.getData_type() except KeyError: atype = StringType if atype in StringType or \ atype == TokenType or \ atype == DateTimeType or \ atype == DateType: add(', %s=\'\'' % mappedName) elif atype in IntegerType: add(', %s=-1' % mappedName) elif atype == PositiveIntegerType: add(', %s=1' % mappedName) elif atype == NonPositiveIntegerType: add(', %s=0' % mappedName) elif atype == NegativeIntegerType: add(', %s=-1' % mappedName) elif atype == NonNegativeIntegerType: add(', %s=0' % mappedName) elif atype == BooleanType: add(', %s=0' % mappedName) elif atype == FloatType or atype == DoubleType or atype == DecimalType: add(', %s=0.0' % mappedName) else: add(', %s=None' % mappedName) nestedElements = 0 for child in element.getChildren(): nestedElements = 1 if child.getMaxOccurs() > 1: add(', %s=None' % child.getCleanName()) else: childType = child.getType() if childType in StringType or \ childType == TokenType or \ childType == DateTimeType or \ childType == DateType: add(', %s=\'\'' % child.getCleanName()) elif childType in IntegerType: add(', %s=-1' % child.getCleanName()) elif childType == PositiveIntegerType: add(', %s=1' % child.getCleanName()) elif childType == NonPositiveIntegerType: add(', %s=0' % child.getCleanName()) elif childType == NegativeIntegerType: add(', %s=-1' % child.getCleanName()) elif childType == NonNegativeIntegerType: add(', %s=0' % child.getCleanName()) elif childType == BooleanType: add(', %s=0' % child.getCleanName()) elif childType == FloatType or \ childType == DoubleType or \ childType == DecimalType: add(', %s=0.0' % child.getCleanName()) else: add(', %s=None' % child.getCleanName()) MixedCtorInitializers = '''\ if mixedclass_ is None: self.mixedclass_ = MixedContainer else: self.mixedclass_ = mixedclass_ if content_ is None: self.content_ = [] else: self.content_ = content_ ''' def generateCtor(outfile, element): s2 = buildCtorArgs_multilevel(element) s1 = ' def __init__(self%s):\n' % s2 outfile.write(s1) base = element.getBase() if base and base in ElementDict: parent = ElementDict[base] s2 = buildCtorParams(parent) s1 = ' %s.__init__(self%s)\n' % (base, s2, ) outfile.write(s1) attrDefs = element.getAttributeDefs() for key in attrDefs: attrDef = attrDefs[key] mappedName = cleanupName(attrDef.getName()) mappedName = mapName(mappedName) s1 = ' self.%s = %s\n' % (mappedName, mappedName) outfile.write(s1) member = 1 # Generate member initializers in ctor. if element.isMixed(): outfile.write(MixedCtorInitializers) else: member = 0 nestedElements = 0 for child in element.getChildren(): name = cleanupName(child.getCleanName()) if child.getMaxOccurs() > 1: s1 = ' if %s is None:\n' % (name, ) outfile.write(s1) s1 = ' self.%s = []\n' % (name, ) outfile.write(s1) s1 = ' else:\n' outfile.write(s1) s1 = ' self.%s = %s\n' % \ (name, name) outfile.write(s1) else: s1 = ' self.%s = %s\n' % \ (name, name) outfile.write(s1) member = 1 nestedElements = 1 if not nestedElements: s1 = ' self.valueOf_ = valueOf_\n' outfile.write(s1) member = 1 if element.getAnyAttribute(): s1 = ' self.anyAttributes_ = {}\n' outfile.write(s1) member = 1 if not member: outfile.write(' pass\n') # Generate get/set/add member functions. def generateGettersAndSetters(outfile, element): nestedElements = 0 for child in element.getChildren(): nestedElements = 1 name = cleanupName(child.getCleanName()) unmappedName = cleanupName(child.getName()) capName = unmappedName.capitalize() s1 = ' def get%s(self): return self.%s\n' % \ (capName, name) outfile.write(s1) s1 = ' def set%s(self, %s): self.%s = %s\n' % \ (capName, name, name, name) outfile.write(s1) if child.getMaxOccurs() > 1: s1 = ' def add%s(self, value): self.%s.append(value)\n' % \ (capName, name) outfile.write(s1) s1 = ' def insert%s(self, index, value): self.%s[index] = value\n' % \ (capName, name) outfile.write(s1) if GenerateProperties: s1 = ' %sProp = property(get%s, set%s)\n' % \ (unmappedName, capName, capName) outfile.write(s1) attrDefs = element.getAttributeDefs() for key in attrDefs: attrDef = attrDefs[key] name = cleanupName(attrDef.getName().replace(':', '_')) mappedName = mapName(name) capName = mappedName.capitalize() s1 = ' def get%s(self): return self.%s\n' % \ (name.capitalize(), mappedName) outfile.write(s1) # # What? An attribute cannot occur multiple times on the same # element. No attribute is a list of values. Right? ## if element.getMaxOccurs() > 1: ## s1 = ' def add%s(self, %s): self.%s.append(%s)\n' % \ ## (capName, mappedName, mappedName, mappedName) ## outfile.write(s1) ## s1 = ' def set%s(self, %s, index): self.%s[index] = %s\n' % \ ## (name.capitalize(), mappedName, mappedName, mappedName) ## outfile.write(s1) ## else: s1 = ' def set%s(self, %s): self.%s = %s\n' % \ (name.capitalize(), mappedName, mappedName, mappedName) outfile.write(s1) if GenerateProperties: s1 = ' %sProp = property(get%s, set%s)\n' % \ (mappedName, capName, capName) outfile.write(s1) if not nestedElements: s1 = ' def getValueOf_(self): return self.valueOf_\n' outfile.write(s1) s1 = ' def setValueOf_(self, valueOf_): self.valueOf_ = valueOf_\n' outfile.write(s1) if element.getAnyAttribute(): s1 = ' def getAnyAttributes_(self): return self.anyAttributes_\n' outfile.write(s1) s1 = ' def setAnyAttributes_(self, anyAttributes_): self.anyAttributes_ = anyAttributes_\n' outfile.write(s1) def generateClasses(outfile, prefix, element, delayed): base = element.getBase() wrt = outfile.write if (not element.getChildren()) and (not element.getAttributeDefs()): return # If this element is an extension (has a base) and the base has # not been generated, then postpone it. if base and base in ElementDict: parent = ElementDict[base] parentName = parent.getName() if parentName not in AlreadyGenerated: PostponedExtensions.append(element) return if element.getName() in AlreadyGenerated: return AlreadyGenerated.append(element.getName()) if element.getMixedExtensionError(): print '*** Element %s extension chain contains mixed and non-mixed content. Not generated.' % \ (element.getName(),) return ElementsForSubclasses.append(element) name = element.getCleanName() if GenerateProperties: if base: s1 = 'class %s%s(object, %s):\n' % (prefix, name, base) else: s1 = 'class %s%s(object):\n' % (prefix, name) else: if base: s1 = 'class %s%s(%s):\n' % (prefix, name, base) else: s1 = 'class %s%s:\n' % (prefix, name) wrt(s1) wrt(' subclass = None\n') generateCtor(outfile, element) wrt(' def factory(*args_, **kwargs_):\n') wrt(' if %s%s.subclass:\n' % (prefix, name)) wrt(' return %s%s.subclass(*args_, **kwargs_)\n' % (prefix, name)) wrt(' else:\n') wrt(' return %s%s(*args_, **kwargs_)\n' % (prefix, name)) wrt(' factory = staticmethod(factory)\n') generateGettersAndSetters(outfile, element) generateExportFn(outfile, prefix, element) generateExportLiteralFn(outfile, prefix, element) generateBuildFn(outfile, prefix, element, delayed) wrt('# end class %s\n' % name) wrt('\n\n') # # Generate the SAX handler class for SAX parsing. # SAX_STARTELEMENT_1 = """\ def startElement(self, name, attrs): done = 0 if name == '%s': obj = %s.factory() stackObj = SaxStackElement('%s', obj) self.stack.append(stackObj) done = 1 """ SAX_STARTELEMENT_2 = """\ stackObj = SaxStackElement('%s', obj) self.stack.append(stackObj) done = 1 """ SAX_STARTELEMENT_3 = """\ stackObj = SaxStackElement('%s', None) self.stack.append(stackObj) done = 1 """ SAX_STARTELEMENT_4 = """\ if not done: self.reportError('"%s" element not allowed here.' % name) """ SAX_ATTR_INTEGER = """\ val = attrs.get('%s', None) if val is not None: try: obj.set%s(int(val)) except: self.reportError('"%s" attribute must be integer') """ SAX_ATTR_BOOLEAN = """\ val = attrs.get('%s', None) if val is not None: if val in ('true', '1'): obj.set%s(1) elif val in ('false', '0'): obj.set%s(0) else: self.reportError('"%s" attribute must be boolean ("true", "1", "false", "0")') """ SAX_ATTR_FLOAT = """\ val = attrs.get('%s', None) if val is not None: try: obj.set%s(float(val)) except: self.reportError('"%s" attribute must be float') """ SAX_ATTR_STRING = """\ val = attrs.get('%s', None) if val is not None: obj.set%s(val) """ def getClassName(element): name = element.getCleanName() return name def generateSaxAttributes(wrt, element): attrDefs = element.getAttributeDefs() for key in attrDefs: attrDef = attrDefs[key] name = attrDef.getName() atype = attrDef.getData_type() if atype in IntegerType: s1 = SAX_ATTR_INTEGER % (name, name.capitalize(), name) wrt(s1) ## s1 = " if attrs.get('%s'):\n" % name ## wrt(s1) ## s1 = ' try:\n' ## wrt(s1) ## s1 = " self.%s = int(attrs.get('%s').value)\n" % \ ## (name, name) ## wrt(s1) ## s1 = ' except ValueError:\n' ## wrt(s1) ## s1 = " raise ValueError('Bad integer')\n" ## wrt(s1) elif atype == BooleanType: s1 = SAX_ATTR_BOOLEAN % (name, name.capitalize(), \ name.capitalize(), name) wrt(s1) ## wrt(s1) ## s1 = " if attrs.get('%s'):\n" % name ## wrt(s1) ## s1 = " if attrs.get('%s').value in ('true', '1'):\n" % \ ## name ## wrt(s1) ## s1 = " self.%s = 1\n" % \ ## name ## wrt(s1) ## s1 = " elif attrs.get('%s').value in ('false', '0'):\n" % \ ## name ## wrt(s1) ## s1 = " self.%s = 0\n" % \ ## name ## wrt(s1) ## s1 = ' else:\n' ## wrt(s1) ## s1 = " raise ValueError('Bad boolean')\n" ## wrt(s1) elif atype == FloatType or atype == DoubleType or atype == DecimalType: s1 = SAX_ATTR_FLOAT % (name, name.capitalize(), name) wrt(s1) ## s1 = " if attrs.get('%s'):\n" % name ## wrt(s1) ## s1 = ' try:\n' ## wrt(s1) ## s1 = " self.%s = float(attrs.get('%s').value)\n" % \ ## (name, name) ## wrt(s1) ## s1 = ' except:\n' ## wrt(s1) ## s1 = " raise ValueError('Bad float/double')\n" ## wrt(s1) else: # Assume attr['type'] in StringType or attr['type'] == DateTimeType: s1 = SAX_ATTR_STRING % (name, name.capitalize()) wrt(s1) ## s1 = " if attrs.get('%s'):\n" % name ## wrt(s1) ## s1 = " self.%s = attrs.get('%s').value\n" % (name, name) ## wrt(s1) def generateSAXStartElement_1(wrt, element): origName = element.getName() typeName = cleanupName(mapName(element.getRawType())) className = element.getCleanName() s1 = " elif name == '%s':\n" % origName wrt(s1) if element.isComplex(): s1 = " obj = %s.factory()\n" % cleanupName(typeName) wrt(s1) element1 = SaxElementDict[element.getCleanName()] generateSaxAttributes(wrt, element1) if element.isComplex(): s1 = SAX_STARTELEMENT_2 % className else: s1 = SAX_STARTELEMENT_3 % className wrt(s1) def generateSAXStartElement(outfile, root, elementList): wrt = outfile.write name = root.getChildren()[0].getName() s1 = SAX_STARTELEMENT_1 % (name, name, name) wrt(s1) for element, parent in elementList: generateSAXStartElement_1(wrt, element) s1 = SAX_STARTELEMENT_4 wrt(s1) wrt('\n') SAX_ENDELEMENT_1 = """\ if name == '%s': if len(self.stack) == 1: self.root = self.stack[-1].obj self.stack.pop() done = 1 """ SAX_ENDELEMENT_2 = """\ elif name == '%s': if len(self.stack) >= 2: self.stack[-2].obj.%s%s(self.stack[-1].obj) self.stack.pop() done = 1 """ SAX_ENDELEMENT_3 = """\ elif name == '%s': if len(self.stack) >= 2: content = self.stack[-1].content %s self.stack[-2].obj.%s%s(content) self.stack.pop() done = 1 """ SAX_ENDELEMENT_INT = """\ if content: try: content = int(content) except: self.reportError('"%s" must be integer -- content: %%s' %% content) else: content = -1 """ SAX_ENDELEMENT_FLOAT = """\ if content: try: content = float(content) except: self.reportError('"%s" must be float -- content: %%s' %% content) else: content = -1 """ SAX_ENDELEMENT_BOOLEAN = """\ if content and content in ('true', '1'): content = 1 else: content = 0 """ SAX_ENDELEMENT_4 = """\ if not done: self.reportError('"%s" element not allowed here.' % name) """ def generateParentCheck(parent): s1 = "self.stack[-2].name == '%s'" % getClassName(parent) return s1 ## strList = [] ## for parent in parentList: ## strList.append("self.stack[-2].name == '%s'" % \ ## parent.getName()) ## s1 = ' or '.join(strList) ## if len(parentList) > 1: ## s1 = '(%s)' % s1 ## return s1 def generateSAXEndElement(outfile, root, elementList): wrt = outfile.write s1 = " def endElement(self, name):\n" wrt(s1) s1 = " done = 0\n" wrt(s1) name = root.getChildren()[0].getName() s1 = SAX_ENDELEMENT_1 % (name, ) wrt(s1) for element, parent in elementList: #s2 = generateParentCheck(parent) name = element.getName() capName = element.getUnmappedCleanName().capitalize() if element.isComplex(): if element.getMaxOccurs() > 1: s1 = SAX_ENDELEMENT_2 % (name, 'add', capName) else: s1 = SAX_ENDELEMENT_2 % (name, 'set', capName) else: etype = element.getType() if etype in IntegerType: s3 = SAX_ENDELEMENT_INT % name elif etype == FloatType or etype == DoubleType or etype == DecimalType: s3 = SAX_ENDELEMENT_FLOAT % name elif etype == BooleanType: s3 = SAX_ENDELEMENT_BOOLEAN else: s3 = '' if element.getMaxOccurs() > 1: s1 = SAX_ENDELEMENT_3 % (name, s3, 'add', capName) else: s1 = SAX_ENDELEMENT_3 % (name, s3, 'set', capName) wrt(s1) s1 = SAX_ENDELEMENT_4 wrt(s1) wrt('\n') SAX_HEADER = """\ from xml.sax import handler, make_parser class SaxStackElement: def __init__(self, name='', obj=None): self.name = name self.obj = obj self.content = '' # # SAX handler # class Sax%sHandler(handler.ContentHandler): def __init__(self): self.stack = [] self.root = None def getRoot(self): return self.root def setDocumentLocator(self, locator): self.locator = locator def showError(self, msg): print '*** (showError):', msg sys.exit(-1) """ SAX_FOOTER = """\ def characters(self, chrs, start, end): if len(self.stack) > 0: self.stack[-1].content += chrs[start:end] def reportError(self, mesg): locator = self.locator sys.stderr.write('Doc: %s Line: %d Column: %d\\n' % \\ (locator.getSystemId(), locator.getLineNumber(), locator.getColumnNumber() + 1)) sys.stderr.write(mesg) sys.stderr.write('\\n') sys.exit(-1) #raise RuntimeError """ ##def produceAllElements(element, parent): ## if element.getType() in StringType or \ ## element.getType() in IntegerType or \ ## element.getType() == DecimalType or \ ## element.getType() == FloatType or \ ## element.getType() == DoubleType or \ ## element.getType() == BooleanType or \ ## len(element.getChildren()) != 0: ## yield (element, parent) ## for child in element.getChildren(): ## for element1, parent1 in produceAllElements(child, element): ## yield (element1, parent1) # # This version of produceAllElements does not use 'yield' and is, # therefore, usable with older versions of Python. def produceAllElements_nogen(element, parent, collection): collection.append((element, parent)) for child in element.getChildren(): produceAllElements_nogen(child, element, collection) def generateSAXHndlr(outfile, root): firstElement = root.getChildren()[0] name = firstElement.getName() s1 = SAX_HEADER % cleanupName(name.capitalize()) outfile.write(s1) elementList = [] collection = [] produceAllElements_nogen(root, None, collection) for element, parent in collection: if element == root: continue elementList.append((element, parent)) ## print '(gsh) element: %s/%s/%d parent: %s/%s/%d' % \ ## (element.getUnmappedCleanName(), element.getType(), id(element), ## #(element.getName(), element.getType(), id(element), ## parent.getName(), parent.getType(), id(parent)) ## if parent.getName() == 'booster': ## ipshell('at booster -- Entering ipshell.\\nHit Ctrl-D to exit') ## if element in elementDict: ## elementDict[element].append(parent) ## else: ## elementDict[element] = [parent] elementList1 = [] alreadySeen = [] for element, parent in elementList: if parent == root: continue if element.getName() in alreadySeen: continue alreadySeen.append(element.getName()) elementList1.append((element, parent)) ## print '+' * 20 ## for element, parent in elementList1: ## print '(gsh) element: %s/%s/%d parent: %s/%s/%d' % \ ## (element.getUnmappedCleanName(), element.getType(), id(element), ## #(element.getName(), element.getType(), id(element), ## parent.getName(), parent.getType(), id(parent)) generateSAXStartElement(outfile, root, elementList1) generateSAXEndElement(outfile, root, elementList1) s1 = SAX_FOOTER outfile.write(s1) def collect(element, elements): if element.getName() != 'root': elements.append(element) for child in element.getChildren(): collect(child, elements) TEMPLATE_HEADER = """\ #!/usr/bin/env python # # Generated %s by generateDS.py. # Update it with: python generateDS.py -o generateModel_Module.py generateMetaModel_Module.xsd # # WARNING! All changes made in this file will be lost! # import sys import getopt from xml.dom import minidom from xml.dom import Node # # If you have installed IPython you can uncomment and use the following. # IPython is available from http://ipython.scipy.org/. # ## from IPython.Shell import IPShellEmbed ## args = '' ## ipshell = IPShellEmbed(args, ## banner = 'Dropping into IPython', ## exit_msg = 'Leaving Interpreter, back to program.') # Then use the following line where and when you want to drop into the # IPython shell: # ipshell(' -- Entering ipshell.\\nHit Ctrl-D to exit') # # Support/utility functions. # def showIndent(outfile, level): for idx in range(level): outfile.write(' ') def quote_xml(inStr): s1 = inStr s1 = s1.replace('&', '&') s1 = s1.replace('<', '<') s1 = s1.replace('"', '"') return s1 def quote_python(inStr): s1 = inStr if s1.find("'") == -1: if s1.find('\\n') == -1: return "'%%s'" %% s1 else: return "'''%%s'''" %% s1 else: if s1.find('"') != -1: s1 = s1.replace('"', '\\\\"') if s1.find('\\n') == -1: return '"%%s"' %% s1 else: return '\"\"\"%%s\"\"\"' %% s1 class MixedContainer: # Constants for category: CategoryNone = 0 CategoryText = 1 CategorySimple = 2 CategoryComplex = 3 # Constants for content_type: TypeNone = 0 TypeText = 1 TypeString = 2 TypeInteger = 3 TypeFloat = 4 TypeDecimal = 5 TypeDouble = 6 TypeBoolean = 7 def __init__(self, category, content_type, name, value): self.category = category self.content_type = content_type self.name = name self.value = value def getCategory(self): return self.category def getContenttype(self, content_type): return self.content_type def getValue(self): return self.value def getName(self): return self.name def export(self, outfile, level, name): if self.category == MixedContainer.CategoryText: outfile.write(self.value) elif self.category == MixedContainer.CategorySimple: self.exportSimple(outfile, level, name) else: # category == MixedContainer.CategoryComplex self.value.export(outfile, level, name) def exportSimple(self, outfile, level, name): if self.content_type == MixedContainer.TypeString: outfile.write('<%%s>%%s' %% (self.name, self.value, self.name)) elif self.content_type == MixedContainer.TypeInteger or \\ self.content_type == MixedContainer.TypeBoolean: outfile.write('<%%s>%%d' %% (self.name, self.value, self.name)) elif self.content_type == MixedContainer.TypeFloat or \\ self.content_type == MixedContainer.TypeDecimal: outfile.write('<%%s>%%f' %% (self.name, self.value, self.name)) elif self.content_type == MixedContainer.TypeDouble: outfile.write('<%%s>%%g' %% (self.name, self.value, self.name)) def exportLiteral(self, outfile, level, name): if self.category == MixedContainer.CategoryText: showIndent(outfile, level) outfile.write('MixedContainer(%%d, %%d, "%%s", "%%s"),\\n' %% \\ (self.category, self.content_type, self.name, self.value)) elif self.category == MixedContainer.CategorySimple: showIndent(outfile, level) outfile.write('MixedContainer(%%d, %%d, "%%s", "%%s"),\\n' %% \\ (self.category, self.content_type, self.name, self.value)) else: # category == MixedContainer.CategoryComplex showIndent(outfile, level) outfile.write('MixedContainer(%%d, %%d, "%%s",\\n' %% \\ (self.category, self.content_type, self.name,)) self.value.exportLiteral(outfile, level + 1) showIndent(outfile, level) outfile.write(')\\n') # # Data representation classes. # """ # Fool (and straighten out) the syntax highlighting. # DUMMY = ''' def generateHeader(outfile, prefix): s1 = TEMPLATE_HEADER % time.ctime() outfile.write(s1) TEMPLATE_MAIN = """\ USAGE_TEXT = \"\"\" Usage: python <%(prefix)sParser>.py [ -s ] Options: -s Use the SAX parser, not the minidom parser. \"\"\" def usage(): print USAGE_TEXT sys.exit(-1) # # SAX handler used to determine the top level element. # class SaxSelectorHandler(handler.ContentHandler): def __init__(self): self.topElementName = None def getTopElementName(self): return self.topElementName def startElement(self, name, attrs): self.topElementName = name raise StopIteration def parseSelect(inFileName): infile = file(inFileName, 'r') topElementName = None parser = make_parser() documentHandler = SaxSelectorHandler() parser.setContentHandler(documentHandler) try: try: parser.parse(infile) except StopIteration: topElementName = documentHandler.getTopElementName() if topElementName is None: raise RuntimeError, 'no top level element' topElementName = topElementName.replace('-', '_').replace(':', '_') if topElementName not in globals(): raise RuntimeError, 'no class for top element: %%s' %% topElementName topElement = globals()[topElementName] infile.seek(0) doc = minidom.parse(infile) finally: infile.close() rootNode = doc.childNodes[0] rootObj = topElement.factory() rootObj.build(rootNode) # Enable Python to collect the space used by the DOM. doc = None sys.stdout.write('\\n') rootObj.export(sys.stdout, 0) return rootObj def saxParse(inFileName): parser = make_parser() documentHandler = Sax%(cap_name)sHandler() parser.setDocumentHandler(documentHandler) parser.parse('file:%%s' %% inFileName) root = documentHandler.getRoot() sys.stdout.write('\\n') root.export(sys.stdout, 0) return root def saxParseString(inString): parser = make_parser() documentHandler = Sax%(cap_name)sHandler() parser.setDocumentHandler(documentHandler) parser.feed(inString) parser.close() rootObj = documentHandler.getRoot() #sys.stdout.write('\\n') #rootObj.export(sys.stdout, 0) return rootObj def parse(inFileName): doc = minidom.parse(inFileName) rootNode = doc.documentElement rootObj = %(prefix)s%(root)s.factory() rootObj.build(rootNode) # Enable Python to collect the space used by the DOM. doc = None sys.stdout.write('\\n') rootObj.export(sys.stdout, 0, name_="%(name)s") return rootObj def parseString(inString): doc = minidom.parseString(inString) rootNode = doc.documentElement rootObj = %(prefix)s%(root)s.factory() rootObj.build(rootNode) # Enable Python to collect the space used by the DOM. doc = None sys.stdout.write('\\n') rootObj.export(sys.stdout, 0, name_="%(name)s") return rootObj def parseLiteral(inFileName): doc = minidom.parse(inFileName) rootNode = doc.documentElement rootObj = %(prefix)s%(root)s.factory() rootObj.build(rootNode) # Enable Python to collect the space used by the DOM. doc = None sys.stdout.write('from %(module_name)s import *\\n\\n') sys.stdout.write('rootObj = %(name)s(\\n') rootObj.exportLiteral(sys.stdout, 0, name_="%(name)s") sys.stdout.write(')\\n') return rootObj def main(): args = sys.argv[1:] if len(args) == 2 and args[0] == '-s': saxParse(args[1]) elif len(args) == 1: parse(args[0]) else: usage() if __name__ == '__main__': main() #import pdb #pdb.run('main()') """ # Fool (and straighten out) the syntax highlighting. # DUMMY = ''' def generateMain(outfile, prefix, root): name = root.getChildren()[0].getName() elType = cleanupName(root.getChildren()[0].getType()) if RootElement: rootElement = RootElement else: rootElement = elType params = { 'prefix': prefix, 'cap_name': cleanupName(name.capitalize()), 'name': cleanupName(name), 'module_name': os.path.splitext(os.path.basename(outfile.name))[0], 'root': rootElement, } s1 = TEMPLATE_MAIN % params outfile.write(s1) def buildCtorParams(element): content = [] add = content.append if element.isMixed(): add(', mixedclass_') add(', content_') else: buildCtorParams_aux(add, element) s1 = ''.join(content) return s1 def buildCtorParams_aux(add, element): attrDefs = element.getAttributeDefs() for key in attrDefs: attrDef = attrDefs[key] name = attrDef.getName() cleanName = cleanupName(mapName(name)) add(', %s' % cleanName) for child in element.getChildren(): add(', %s' % child.getCleanName()) base = element.getBase() if base and base in ElementDict: parent = ElementDict[base] buildCtorParams_aux(add, parent) def get_class_behavior_args(classBehavior): argList = [] args = classBehavior.getArgs() args = args.getArg() #print '(get_class_behavior_args) args:', args for arg in args: argList.append(arg.getName()) argString = ', '.join(argList) return argString # # Retrieve the implementation body via an HTTP request to a # URL formed from the concatenation of the baseImplUrl and the # implUrl. # An alternative implementation of get_impl_body() that also # looks in the local file system is commented out below. # def get_impl_body(classBehavior, baseImplUrl, implUrl): impl = ' pass\n' if implUrl: if baseImplUrl: implUrl = '%s%s' % (baseImplUrl, implUrl) try: implFile = urllib2.urlopen(implUrl) impl = implFile.read() implFile.close() except urllib2.HTTPError: print '*** Implementation at %s not found.' % implUrl return impl ### ### This alternative implementation of get_impl_body() tries the URL ### via http first, then, if that fails, looks in a directory on ### the local file system (baseImplUrl) for a file (implUrl) ### containing the implementation body. ### ##def get_impl_body(classBehavior, baseImplUrl, implUrl): ## impl = ' pass\n' ## if implUrl: ## trylocal = 0 ## if baseImplUrl: ## implUrl = '%s%s' % (baseImplUrl, implUrl) ## try: ## implFile = urllib2.urlopen(implUrl) ## impl = implFile.read() ## implFile.close() ## except: ## trylocal = 1 ## if trylocal: ## try: ## implFile = file(implUrl) ## impl = implFile.read() ## implFile.close() ## except: ## print '*** Implementation at %s not found.' % implUrl ## return impl def generateClassBehaviors(wrt, classBehaviors, baseImplUrl): for classBehavior in classBehaviors: behaviorName = classBehavior.getName() # # Generate the core behavior. argString = get_class_behavior_args(classBehavior) if argString: wrt(' def %s(self, %s, *args):\n' % (behaviorName, argString)) else: wrt(' def %s(self, *args):\n' % (behaviorName, )) implUrl = classBehavior.getImpl_url() impl = get_impl_body(classBehavior, baseImplUrl, implUrl) wrt(impl) wrt('\n') # # Generate the ancillaries for this behavior. ancillaries = classBehavior.getAncillaries() if ancillaries: ancillaries = ancillaries.getAncillary() if ancillaries: for ancillary in ancillaries: argString = get_class_behavior_args(ancillary) if argString: wrt(' def %s(self, %s, *args):\n' % (ancillary.getName(), argString)) else: wrt(' def %s(self, *args):\n' % (ancillary.getName(), )) implUrl = ancillary.getImpl_url() impl = get_impl_body(classBehavior, baseImplUrl, implUrl) wrt(impl) wrt('\n') # # Generate the wrapper method that calls the ancillaries and # the core behavior. argString = get_class_behavior_args(classBehavior) if argString: wrt(' def %s_wrapper(self, %s, *args):\n' % (behaviorName, argString)) else: wrt(' def %s_wrapper(self, *args):\n' % (behaviorName, )) if ancillaries: for ancillary in ancillaries: role = ancillary.getRole() if role == 'DBC-precondition': wrt(' if not self.%s(*args)\n' % (ancillary.getName(), )) wrt(' return False\n') if argString: wrt(' result = self.%s(%s, *args)\n' % (behaviorName, argString)) else: wrt(' result = self.%s(*args)\n' % (behaviorName, )) if ancillaries: for ancillary in ancillaries: role = ancillary.getRole() if role == 'DBC-postcondition': wrt(' if not self.%s(*args)\n' % (ancillary.getName(), )) wrt(' return False\n') wrt(' return result\n') wrt('\n') def generateSubclass(outfile, element, prefix, xmlbehavior, behaviors, baseUrl): wrt= outfile.write if not element.isComplex(): return if (not element.getChildren()) and (not element.getAttributeDefs()): return if element.getName() in AlreadyGenerated_subclass: return AlreadyGenerated_subclass.append(element.getName()) name = element.getCleanName() wrt('class %s%s%s(supermod.%s):\n' % (prefix, name, SubclassSuffix, name)) s1 = buildCtorArgs_multilevel(element) wrt(' def __init__(self%s):\n' % s1) s1 = buildCtorParams(element) wrt(' supermod.%s%s.__init__(self%s)\n' % (prefix, name, s1)) if xmlbehavior and behaviors: wrt('\n') wrt(' #\n') wrt(' # XMLBehaviors\n') wrt(' #\n') # Get a list of behaviors for this class/subclass. classDictionary = behaviors.get_class_dictionary() if name in classDictionary: classBehaviors = classDictionary[name] else: classBehaviors = None if classBehaviors: generateClassBehaviors(wrt, classBehaviors, baseUrl) wrt('supermod.%s.subclass = %s%s\n' % (name, name, SubclassSuffix)) wrt('# end class %s%s%s\n' % (prefix, name, SubclassSuffix)) wrt('\n\n') TEMPLATE_SUBCLASS_HEADER = """\ #!/usr/bin/env python # # Generated %s by generateDS.py. # import sys from xml.dom import minidom from xml.sax import handler, make_parser import %s as supermod """ TEMPLATE_SUBCLASS_FOOTER = """\ # # SAX handler used to determine the top level element. # class SaxSelectorHandler(handler.ContentHandler): def __init__(self): self.topElementName = None def getTopElementName(self): return self.topElementName def startElement(self, name, attrs): self.topElementName = name raise StopIteration def parseSelect(inFileName): infile = file(inFileName, 'r') topElementName = None parser = make_parser() documentHandler = SaxSelectorHandler() parser.setContentHandler(documentHandler) try: try: parser.parse(infile) except StopIteration: topElementName = documentHandler.getTopElementName() if topElementName is None: raise RuntimeError, 'no top level element' topElementName = topElementName.replace('-', '_').replace(':', '_') if topElementName not in supermod.__dict__: raise RuntimeError, 'no class for top element: %%s' %% topElementName topElement = supermod.__dict__[topElementName] infile.seek(0) doc = minidom.parse(infile) finally: infile.close() rootNode = doc.childNodes[0] rootObj = topElement.factory() rootObj.build(rootNode) # Enable Python to collect the space used by the DOM. doc = None sys.stdout.write('\\n') rootObj.export(sys.stdout, 0) return rootObj def saxParse(inFileName): parser = make_parser() documentHandler = supermod.Sax%(cap_name)sHandler() parser.setDocumentHandler(documentHandler) parser.parse('file:%%s' %% inFileName) rootObj = documentHandler.getRoot() #sys.stdout.write('\\n') #rootObj.export(sys.stdout, 0) return rootObj def saxParseString(inString): parser = make_parser() documentHandler = supermod.SaxContentHandler() parser.setDocumentHandler(documentHandler) parser.feed(inString) parser.close() rootObj = documentHandler.getRoot() #sys.stdout.write('\\n') #rootObj.export(sys.stdout, 0) return rootObj def parse(inFilename): doc = minidom.parse(inFilename) rootNode = doc.documentElement rootObj = supermod.%(root)s.factory() rootObj.build(rootNode) # Enable Python to collect the space used by the DOM. doc = None sys.stdout.write('\\n') rootObj.export(sys.stdout, 0, name_="%(name)s") doc = None return rootObj def parseString(inString): doc = minidom.parseString(inString) rootNode = doc.documentElement rootObj = supermod.%(root)s.factory() rootObj.build(rootNode) # Enable Python to collect the space used by the DOM. doc = None sys.stdout.write('\\n') rootObj.export(sys.stdout, 0, name_="%(name)s") return rootObj def parseLiteral(inFilename): doc = minidom.parse(inFilename) rootNode = doc.documentElement rootObj = supermod.%(root)s.factory() rootObj.build(rootNode) # Enable Python to collect the space used by the DOM. doc = None sys.stdout.write('from %(super)s import *\\n\\n') sys.stdout.write('rootObj = %(name)s(\\n') rootObj.exportLiteral(sys.stdout, 0, name_="%(name)s") sys.stdout.write(')\\n') return rootObj USAGE_TEXT = \"\"\" Usage: python ???.py \"\"\" def usage(): print USAGE_TEXT sys.exit(-1) def main(): args = sys.argv[1:] if len(args) != 1: usage() infilename = args[0] root = parse(infilename) if __name__ == '__main__': main() #import pdb #pdb.run('main()') """ ##def isMember(item, lst): ## for item1 in lst: ## if item == item1: ## print '(isMember) found name: %s' % item ## return True ## print '(isMember) did not find name: %s' % item ## return False def generateSubclasses(root, subclassFilename, behaviorFilename, prefix, superModule='xxx'): name = root.getChildren()[0].getName() subclassFile = makeFile(subclassFilename) if subclassFile: # Read in the XMLBehavior file. xmlbehavior = None behaviors = None baseUrl = None if behaviorFilename: try: # Add the currect working directory to the path so that # we use the user/developers local copy. sys.path.insert(0, '.') import xmlbehavior_sub as xmlbehavior except ImportError: print '*** You have requested generation of extended methods.' print '*** But, no xmlbehavior module is available.' print '*** Generation of extended behavior methods is omitted.' if xmlbehavior: behaviors = xmlbehavior.parse(behaviorFilename) behaviors.make_class_dictionary(cleanupName) baseUrl = behaviors.getBase_impl_url() wrt = subclassFile.write wrt(TEMPLATE_SUBCLASS_HEADER % (time.ctime(), superModule)) for element in ElementsForSubclasses: generateSubclass(subclassFile, element, prefix, xmlbehavior, behaviors, baseUrl) ## processed = [] ## for element in root.getChildren(): ## name = element.getCleanName() ## if name not in processed: ## processed.append(name) ## generateSubclass(subclassFile, element, prefix, xmlbehavior, behaviors, baseUrl) ## while 1: ## if len(DelayedElements_subclass) <= 0: ## break ## element = DelayedElements_subclass.pop() ## name = element.getCleanName() ## if name not in processed: ## processed.append(name) ## generateSubclass(subclassFile, element, prefix, xmlbehavior, behaviors, baseUrl) name = root.getChildren()[0].getName() elType = cleanupName(root.getChildren()[0].getType()) if RootElement: rootElement = RootElement else: rootElement = elType params = { 'cap_name': cleanupName(name).capitalize(), 'name': cleanupName(name), 'module_name': os.path.splitext(os.path.basename(subclassFilename))[0], 'root': rootElement, 'super': superModule, } wrt(TEMPLATE_SUBCLASS_FOOTER % params) subclassFile.close() def generateFromTree(outfile, prefix, elements, processed): for element in elements: name = element.getCleanName() if 1: # if name not in processed: processed.append(name) generateClasses(outfile, prefix, element, 0) children = element.getChildren() if children: generateFromTree(outfile, prefix, element.getChildren(), processed) def generate(outfileName, subclassFilename, behaviorFilename, prefix, root, superModule): global DelayedElements, DelayedElements_subclass # Create an output file. # Note that even if the user does not request an output file, # we still need to go through the process of generating classes # because it produces data structures needed during generation of # subclasses. outfile = None if outfileName: outfile = makeFile(outfileName) if not outfile: outfile = os.tmpfile() processed = [] generateHeader(outfile, prefix) DelayedElements = [] DelayedElements_subclass = [] elements = root.getChildren() generateFromTree(outfile, prefix, elements, processed) while 1: if len(DelayedElements) <= 0: break element = DelayedElements.pop() name = element.getCleanName() if name not in processed: processed.append(name) generateClasses(outfile, prefix, element, 1) # # Generate the elements that were postponed because we had not # yet generated their base class. idx = 0 while 1: if len(PostponedExtensions) <= 0: break element = PostponedExtensions.pop() base = element.getBase() if base and base in ElementDict: parent = ElementDict[base] parentName = parent.getName() if parentName not in AlreadyGenerated: PostponedExtensions.insert(0, element) else: idx += 1 generateClasses(outfile, prefix, element, 1) # # Disable the generation of SAX handler/parser. # It failed when we stopped putting simple types into ElementDict. # When there are duplicate names, the SAX parser probably does # not work anyway. generateSAXHndlr(outfile, root) generateMain(outfile, prefix, root) outfile.close() if subclassFilename: generateSubclasses(root, subclassFilename, behaviorFilename, prefix, superModule) def makeFile(outFileName): global Force outFile = None if (not Force) and os.path.exists(outFileName): reply = raw_input('File %s exists. Overwrite? (y/n): ' % outFileName) if reply == 'y': outFile = file(outFileName, 'w') else: outFile = file(outFileName, 'w') return outFile def mapName(oldName): global NameTable newName = oldName if NameTable: if oldName in NameTable: newName = NameTable[oldName] return newName def cleanupName(oldName): newName = oldName.replace(':', '_') newName = newName.replace('-', '_') return newName ## def mapName(oldName): ## return '_X_%s' % oldName def strip_namespace(val): return val.split(':')[-1] def parseAndGenerate(outfileName, subclassFilename, prefix, \ xschemaFileName, behaviorFilename, superModule='???'): global DelayedElements, DelayedElements_subclass, AlreadyGenerated, SaxDelayedElements, \ AlreadyGenerated_subclass DelayedElements = [] DelayedElements_subclass = [] AlreadyGenerated = [] AlreadyGenerated_subclass = [] ## parser = saxexts.make_parser("xml.sax.drivers2.drv_pyexpat") parser = make_parser() ## print 'dir(parser):', dir(parser) ## print "Parser: %s" % parser dh = XschemaHandler() ## parser.setDocumentHandler(dh) parser.setContentHandler(dh) parser.parse(xschemaFileName) root = dh.getRoot() root.annotate() ## print 'ElementDict:', ElementDict ## for name, obj in ElementDict.iteritems(): ## print ' ', name, obj.getName(), obj.type ## print '=' * 50 ## root.show(sys.stdout, 0) ## print '=' * 50 ## response = raw_input('Press Enter') ## root.show(sys.stdout, 0) ## print '=' * 50 ## print ']]] root: ', root, '[[[' generate(outfileName, subclassFilename, behaviorFilename, prefix, root, superModule) USAGE_TEXT = """ Usage: python generateDS.py [ options ] Options: -o Output file name for data representation classes -s Output file name for subclasses -p Prefix string to be pre-pended to the class names -n Transform names with table in mappingfilename. -f Force creation of output files. Do not ask. -a Namespace abbreviation, e.g. "xsd:". Default = 'xs:'. -b Input file name for behaviors added to subclasses -m Generate properties for member variables --subclass-suffix="XXX" Append XXX to the generated subclass names. Default="Sub". --root-element="XXX" Assume XXX is root element of instance docs. Default is first element defined in schema. --super="XXX" Super module name in subclass module. Default="???" Example: python generateDS.py -o generateModel_Module.py generateMetaModel_Module.xsd """ def usage(): print USAGE_TEXT sys.exit(-1) def main(): global Force, GenerateProperties, SubclassSuffix, RootElement args = sys.argv[1:] options, args = getopt.getopt(args, 'fyo:s:p:a:b:m', ['subclass-suffix=', 'root-element=', 'super=', ]) prefix = '' outFilename = None subclassFilename = None behaviorFilename = None nameSpace = 'xs:' debug = 0 superModule = '???' for option in options: if option[0] == '-p': prefix = option[1] elif option[0] == '-o': outFilename = option[1] elif option[0] == '-s': subclassFilename = option[1] elif option[0] == '-f': Force = 1 elif option[0] == '-a': nameSpace = option[1] elif option[0] == '-b': behaviorFilename = option[1] elif option[0] == '-m': GenerateProperties = 1 elif option[0] == '--subclass-suffix': SubclassSuffix = option[1] elif option[0] == '--root-element': RootElement = option[1] elif option[0] == '--super': superModule = option[1] set_type_constants(nameSpace) if behaviorFilename and not subclassFilename: print '\n*** Error. -b requires -s' usage() if len(args) != 1: usage() xschemaFileName = args[0] if debug: pass else: parseAndGenerate(outFilename, subclassFilename, prefix, \ xschemaFileName, behaviorFilename, superModule=superModule) if __name__ == '__main__': main() ## import pdb ## pdb.run('main()')