AbdulElahGwaith's picture
Upload folder using huggingface_hub
985c397 verified
#!/usr/bin/env python
# SPDX-License-Identifier: MIT
## 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.
import sys
import os.path
import time
import getopt
from urllib.request import urlopen
from urllib.error import HTTPError
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('<some message> -- 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 correct 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 definitions 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 = "<empty>"
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:
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:
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 and "name" in attrs:
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:
name = attrs["name"]
# fix-attribute-ref
elif "ref" in attrs:
name = strip_namespace(attrs["ref"])
else:
name = "no_attribute_name"
if "type" in attrs:
data_type = attrs["type"]
else:
data_type = StringType[0]
if "use" in attrs:
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:
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:
self.stack[-1].attributeGroupNameList.append(attrs["ref"])
elif name == ComplexContentType:
pass
elif name == ExtensionType:
if "base" in attrs 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</%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</%s>\\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</%s>\\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</%s>\\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</%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</%s>\\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</%s>\\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</%s>\\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('</%s>\\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 python3
#
# 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('<some message> -- 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('&', '&amp;')
s1 = s1.replace('<', '&lt;')
s1 = s1.replace('"', '&quot;')
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</%%s>' %% (self.name, self.value, self.name))
elif self.content_type == MixedContainer.TypeInteger or \\
self.content_type == MixedContainer.TypeBoolean:
outfile.write('<%%s>%%d</%%s>' %% (self.name, self.value, self.name))
elif self.content_type == MixedContainer.TypeFloat or \\
self.content_type == MixedContainer.TypeDecimal:
outfile.write('<%%s>%%f</%%s>' %% (self.name, self.value, self.name))
elif self.content_type == MixedContainer.TypeDouble:
outfile.write('<%%s>%%g</%%s>' %% (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 ] <in_xml_file>
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 = open(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('<?xml version="1.0" ?>\\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('<?xml version="1.0" ?>\\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('<?xml version="1.0" ?>\\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('<?xml version="1.0" ?>\\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('<?xml version="1.0" ?>\\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 = urlopen(implUrl)
impl = implFile.read()
implFile.close()
except 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 = urlopen(implUrl)
## impl = implFile.read()
## implFile.close()
## except:
## trylocal = 1
## if trylocal:
## try:
## implFile = open(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 = open(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('<?xml version="1.0" ?>\\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('<?xml version="1.0" ?>\\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('<?xml version="1.0" ?>\\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('<?xml version="1.0" ?>\\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('<?xml version="1.0" ?>\\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 <infilename>
\"\"\"
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 correct 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 = input("File %s exists. Overwrite? (y/n): " % outFileName)
if reply == "y":
outFile = open(outFileName, "w")
else:
outFile = open(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.items():
## print ' ', name, obj.getName(), obj.type
## print '=' * 50
## root.show(sys.stdout, 0)
## print '=' * 50
## response = 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 ] <in_xsd_file>
Options:
-o <outfilename> Output file name for data representation classes
-s <subclassfilename> Output file name for subclasses
-p <prefix> Prefix string to be prepended to the class names
-n <mappingfilename> Transform names with table in mappingfilename.
-f Force creation of output files. Do not ask.
-a <namespaceabbrev> Namespace abbreviation, e.g. "xsd:". Default = 'xs:'.
-b <behaviorfilename> 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()')