--- a/xmlclass/xmlclass.py Fri Aug 31 15:08:11 2007 +0200
+++ b/xmlclass/xmlclass.py Fri Aug 31 15:09:05 2007 +0200
@@ -88,8 +88,10 @@
return False
else:
raise ValueError, "\"%s\" is not a valid boolean!"%value
- elif type_compute in ["decimal","unsignedLong","long","integer"]:
+ elif type_compute in ["unsignedLong","long","integer"]:
return int(value)
+ elif type_compute == "decimal":
+ return float(value)
elif type_compute in ["string","anyURI","NMTOKEN","language"]:
return value
elif type_compute == "time":
@@ -123,6 +125,11 @@
print "Can't affect: %s"%type_compute
return None
+def GetInitialValueFunction(value):
+ def GetInitialValue():
+ return value
+ return GetInitialValue
+
"""
Class that generate class from an XML Tree
"""
@@ -158,6 +165,7 @@
# This tags defines an attribute of the class
if name in ["element", "attribute"]:
nodename = GetAttributeValue(node._attrs["name"])
+ default = None
if "type" in node._attrs:
nodetype = GetAttributeValue(node._attrs["type"])
if nodetype.startswith("xsd"):
@@ -179,7 +187,9 @@
use = GetAttributeValue(node._attrs["use"])
else:
use = "optional"
- if name == "element":
+ if "default" in node._attrs:
+ default = GetAttributeValue(node._attrs["default"])
+ elif name == "element":
# If a tag can be written more than one time we define a list attribute
if "maxOccurs" in node._attrs and GetAttributeValue(node._attrs["maxOccurs"]) == "unbounded":
nodetype = "%s[]"%nodetype
@@ -187,7 +197,7 @@
use = "optional"
else:
use = "required"
- attributes[nodename] = (nodetype, name, use)
+ attributes[nodename] = (nodetype, name, use, default)
if sequence:
order.append(nodename)
@@ -214,7 +224,7 @@
choices = attrs
else:
choices = {}
- for attr, (attr_type, xml_type, write_type) in attrs.items():
+ for attr, (attr_type, xml_type, write_type, default) in attrs.items():
choices[attr] = attr_type
if "maxOccurs" in node._attrs and GetAttributeValue(node._attrs["maxOccurs"]) == "unbounded":
attributes["multichoice_content"] = choices
@@ -230,11 +240,11 @@
elif name in "sequence":
super, attrs, order = self.GenerateXSDClasses(node, parent, True)
if "maxOccurs" in node._attrs and GetAttributeValue(node._attrs["maxOccurs"]) == "unbounded":
- for attr, (attr_type, xml_type, write_type) in attrs.items():
- attrs[attr] = ("%s[]"%attr_type, xml_type, write_type)
+ for attr, (attr_type, xml_type, write_type, default) in attrs.items():
+ attrs[attr] = ("%s[]"%attr_type, xml_type, write_type, default)
if "minOccurs" in node._attrs and GetAttributeValue(node._attrs["minOccurs"]) == "0":
- for attr, (attr_type, xml_type, write_type) in attrs.items():
- attrs[attr] = (attr_type, xml_type, "optional")
+ for attr, (attr_type, xml_type, write_type, default) in attrs.items():
+ attrs[attr] = (attr_type, xml_type, "optional", default)
inheritance.extend(super)
attributes.update(attrs)
attributes["order"] = order
@@ -315,28 +325,107 @@
"""
Funtion that returns the Python type and default value for a given type
"""
- def GetTypeInitialValue(self, attr_type):
+ def GetTypeInitialValue(self, attr_type, default = None):
type_compute = attr_type[4:].replace("[]", "")
if attr_type.startswith("bse:"):
if type_compute == "boolean":
- return BooleanType, "False"
- elif type_compute in ["decimal","unsignedLong","long","integer"]:
- return IntType, "0"
+ if default:
+ def GetBooleanInitialValue():
+ return default == "true"
+ return BooleanType, GetBooleanInitialValue
+ else:
+ return BooleanType, lambda:False
+ elif type_compute in ["unsignedLong","long","integer"]:
+ if default:
+ def GetIntegerInitialValue():
+ return int(default)
+ return IntType, GetIntegerInitialValue
+ else:
+ return IntType, lambda:0
+ elif type_compute == "decimal":
+ if default:
+ def GetFloatInitialValue():
+ return float(default)
+ return FloatType, GetFloatInitialValue
+ else:
+ return FloatType, lambda:0.
elif type_compute in ["string","anyURI","NMTOKEN"]:
- return StringType, "\"\""
+ if default:
+ def GetStringInitialValue():
+ return default
+ return StringType, GetStringInitialValue
+ else:
+ return StringType, lambda:""
elif type_compute == "time":
- return TimeType, "time(0,0,0,0)"
+ if default:
+ def GetTimeInitialValue():
+ result = time_model.match(value)
+ if result:
+ values = result.groups()
+ time_values = [int(v) for v in values[:2]]
+ seconds = float(values[2])
+ time_values.extend([int(seconds), int((seconds % 1) * 1000000)])
+ return time(*time_values)
+ return time(0,0,0,0)
+ return TimeType, GetTimeInitialValue
+ else:
+ return TimeType, lambda:time(0,0,0,0)
elif type_compute == "date":
- return DateType, "date(1,1,1)"
+ if default:
+ def GetDateInitialValue():
+ result = date_model.match(value)
+ if result:
+ date_values = [int(v) for v in result.groups()]
+ return date(*date_values)
+ return date(1,1,1)
+ return DateType, GetDateInitialValue
+ else:
+ return DateType, lambda:date(1,1,1)
elif type_compute == "dateTime":
- return DateTimeType, "datetime(1,1,1,0,0,0,0)"
+ if default:
+ def GetDateTimeInitialValue():
+ result = datetime_model.match(value)
+ if result:
+ values = result.groups()
+ datetime_values = [int(v) for v in values[:5]]
+ seconds = float(values[5])
+ datetime_values.extend([int(seconds), int((seconds % 1) * 1000000)])
+ return datetime(*datetime_values)
+ return datetime(1,1,1,0,0,0,0)
+ return DateTimeType, GetDateTimeInitialValue
+ else:
+ return DateTimeType, lambda:datetime(1,1,1,0,0,0,0)
elif type_compute == "language":
- return StringType, "\"en-US\""
+ if default:
+ def GetStringInitialValue():
+ return default
+ return StringType, GetStringInitialValue
+ else:
+ return StringType, lambda:"en-US"
else:
print "Can't affect: %s"%type_compute
elif attr_type.startswith("cls:"):
if self.XMLClassDefinitions.get(type_compute, None) != None:
- return self.XMLClassDefinitions[type_compute],"%s()"%type_compute
+ def GetClassInitialValue():
+ if self.XMLClassDefinitions.get(type_compute, None) != None:
+ obj = self.ComputedClasses[type_compute]()
+ if default:
+ obj.setValue(default)
+ return obj
+ return None
+ return self.XMLClassDefinitions[type_compute], GetClassInitialValue
+ return None, lambda:None
+
+ """
+ Funtion that returns the Python type and default value for a given type
+ """
+ def GetInitialValues(self, value_types):
+ initial_values = {}
+ for name, value_type in value_types.items():
+ result = self.GetTypeInitialValue(value_type)
+ if result:
+ initial_values[name] = result[1]
+ return initial_values
"""
Methods that generate the classes
@@ -396,20 +485,20 @@
# Class is a enumerated type
elif attr == "enum":
value_type, initial = self.GetTypeInitialValue(members["basetype"])
- initialValues["value"] = "\"%s\""%values[0]
+ initialValues["value"] = GetInitialValueFunction(values[0])
classmembers["value"] = values[0]
classmembers["setValue"] = generateSetEnumMethod(values, value_type)
classmembers["getValue"] = generateGetMethod("value")
+ classmembers["getValidValues"] = generateGetChoicesMethod(values)
# Class is a limited type
elif attr == "limit":
value_type, initial = self.GetTypeInitialValue(members["basetype"])
- initial = 0
if "min" in values:
initial = max(initial, values["min"])
if "max" in values:
initial = min(initial, values["max"])
- initialValues["value"] = "%d"%initial
+ initialValues["value"] = GetInitialValueFunction(initial)
classmembers["value"] = initial
classmembers["setValue"] = generateSetLimitMethod(values, value_type)
classmembers["getValue"] = generateGetMethod("value")
@@ -417,29 +506,33 @@
# Class has an attribute that can have different value types
elif attr == "choice_content":
classmembers["content"] = None
- initialValues["content"] = "None"
+ initialValues["content"] = lambda:None
classmembers["deleteContent"] = generateDeleteMethod("content")
+ classmembers["addContent"] = generateAddChoiceMethod(values, self.GetInitialValues(values))
classmembers["setContent"] = generateSetChoiceMethod(values)
classmembers["getContent"] = generateGetMethod("content")
+ classmembers["getChoices"] = generateGetChoicesMethod(values)
elif attr == "multichoice_content":
classmembers["content"] = []
- initialValues["content"] = "[]"
+ initialValues["content"] = lambda:[]
classmembers["appendContent"] = generateAppendChoiceMethod(values)
+ classmembers["appendContentByType"] = generateAppendChoiceByTypeMethod(values, self.GetInitialValues(values))
classmembers["insertContent"] = generateInsertChoiceMethod(values)
classmembers["removeContent"] = generateRemoveMethod("content")
classmembers["countContent"] = generateCountMethod("content")
classmembers["setContent"] = generateSetMethod("content", ListType)
classmembers["getContent"] = generateGetMethod("content")
+ classmembers["getChoices"] = generateGetChoicesMethod(values)
# It's an attribute of the class
else:
attrname = attr[0].upper()+attr[1:]
- attr_type, xml_type, write_type = values
- value_type, initial = self.GetTypeInitialValue(attr_type)
+ attr_type, xml_type, write_type, default = values
+ value_type, initial = self.GetTypeInitialValue(attr_type, default)
# Value of the attribute is a list
if attr_type.endswith("[]"):
classmembers[attr] = []
- initialValues[attr] = "[]"
+ initialValues[attr] = lambda:[]
classmembers["append"+attrname] = generateAppendMethod(attr, value_type)
classmembers["insert"+attrname] = generateInsertMethod(attr, value_type)
classmembers["remove"+attrname] = generateRemoveMethod(attr)
@@ -448,18 +541,18 @@
else:
if write_type == "optional":
classmembers[attr] = None
- initialValues[attr] = "None"
- classmembers["add"+attrname] = generateAddMethod(attr, initial, self.ComputedClasses)
+ initialValues[attr] = lambda:None
+ classmembers["add"+attrname] = generateAddMethod(attr, initial)
classmembers["delete"+attrname] = generateDeleteMethod(attr)
else:
- classmembers[attr] = initial
+ classmembers[attr] = initial()
initialValues[attr] = initial
classmembers["set"+attrname] = generateSetMethod(attr, value_type)
classmembers["get"+attrname] = generateGetMethod(attr)
- classmembers["__init__"] = generateInitMethod(bases, initialValues, self.ComputedClasses)
+ classmembers["__init__"] = generateInitMethod(bases, initialValues)
classmembers["loadXMLTree"] = generateLoadXMLTree(bases, members, self.ComputedClasses)
classmembers["generateXMLText"] = generateGenerateXMLText(bases, members)
- classmembers["getElementAttributes"] = generategetElementAttributes(bases, members)
+ classmembers["getElementAttributes"] = generateGetElementAttributes(bases, members, self.ComputedClasses)
classmembers["singleLineAttributes"] = True
self.ComputedClasses[classname] = classobj(classname, bases, classmembers)
@@ -528,7 +621,7 @@
# Load the node attributes if they are defined in the list
for attrname, attr in tree._attrs.items():
if attrname in members.keys():
- attr_type, xml_type, write_type = members[attrname]
+ attr_type, xml_type, write_type, default = members[attrname]
attr_value = GetAttributeValue(attr)
if write_type != "optional" or attr_value != "":
# Extracts the value
@@ -587,7 +680,7 @@
# The node child is defined in the list
elif name in members.keys():
- attr_type, xml_type, write_type = members[name]
+ attr_type, xml_type, write_type, default = members[name]
# Extracts the value
if attr_type.startswith("bse:"):
attr_value = GetAttributeValue(node)
@@ -623,10 +716,10 @@
order = members["order"]
else:
order = []
- if "choice_content" in members.keys() and "choice_content" not in order:
- order.append("choice_content")
- if "multichoice_content" in members.keys() and "multichoice_content" not in order:
- order.append("multichoice_content")
+ for attr, values in members.items():
+ if attr != "order" and (attr in ("choice_content", "multichoice_content") or values[1] != "attribute"):
+ if attr not in order:
+ order.append(attr)
size = 0
first = True
for attr, value in extras.items():
@@ -645,21 +738,16 @@
return text
elif values[1] == "attribute":
value = getattr(self, attr, None)
- if value == "":
- value = None
- if values[2] != "optional" or value != None:
- if not first and not self.singleLineAttributes:
- text += "\n%s"%(ind2)
- if values[0].startswith("cls"):
- if len(bases) > 0:
- base_extras[attr] = value.getValue()
- else:
- text += " %s=\"%s\""%(attr, ComputeValue(value.getValue()))
+ if values[0].startswith("cls"):
+ value = value.getValue()
+ computed_value = ComputeValue(value)
+ if values[2] != "optional" or value != computed_value:
+ if len(bases) > 0:
+ base_extras[attr] = value
else:
- if len(bases) > 0:
- base_extras[attr] = value
- else:
- text += " %s=\"%s\""%(attr, ComputeValue(value))
+ if not first and not self.singleLineAttributes:
+ text += "\n%s"%(ind2)
+ text += " %s=\"%s\""%(attr, computed_value)
first = False
if len(bases) > 0:
first, new_text = bases[0].generateXMLText(self, name, indent, base_extras, True)
@@ -726,31 +814,37 @@
return generateXMLTextMethod
-def generategetElementAttributes(bases, members):
+def generateGetElementAttributes(bases, members, classes):
def getElementAttributes(self):
attr_list = []
for attr, values in members.items():
if attr in ["order","choice_content","multichoice_content"]:
pass
elif values[1] == "attribute":
- if values[2] == "required":
- require = True
- else:
- require = False
- attr_hash ={"name": attr,"type": values[0] ,"value": getattr(self, attr, "") ,"require": require}
- attr_list.append(attr_hash)
+ attr_params = {"name": attr, "require": values[2] == "required"}
+ if values[0].startswith("cls:"):
+ attr_value = getattr(self, attr, None)
+ if attr_value:
+ attr_params["value"] = attr_value.getValue()
+ else:
+ attr_params["value"] = ""
+ attr_params["type"] = classes[values[0][4:]]().getValidValues()
+ else:
+ attr_params["value"] = getattr(self, attr, "")
+ attr_params["type"] = values[0][4:]
+ attr_list.append(attr_params)
return attr_list
return getElementAttributes
"""
Methods that generates the different methods for setting and getting the attributes
"""
-def generateInitMethod(bases, members, classes):
+def generateInitMethod(bases, members):
def initMethod(self):
for base in bases:
base.__init__(self)
for attr, initial in members.items():
- setattr(self, attr, eval(initial, globals().update(classes)))
+ setattr(self, attr, initial())
return initMethod
def generateSetMethod(attr, attr_type):
@@ -758,11 +852,22 @@
setattr(self, attr, value)
return setMethod
+def generateAddChoiceMethod(choice_type, initial_values):
+ def addChoiceMethod(self, name):
+ if name in choice_type:
+ self.content = {"name" : name, "value" : initial_values[name]()}
+ return addChoiceMethod
+
def generateSetChoiceMethod(choice_type):
def setChoiceMethod(self, name, value):
- self.content = {"name":name,"value":value}
+ self.content = {"name" : name, "value" : value}
return setChoiceMethod
+def generateGetChoicesMethod(choice_type):
+ def getChoicesMethod(self):
+ return choice_type
+ return getChoicesMethod
+
def generateSetEnumMethod(enum, attr_type):
def setEnumMethod(self, value):
if value in enum:
@@ -786,9 +891,9 @@
return getattr(self, attr, None)
return getMethod
-def generateAddMethod(attr, initial, classes):
+def generateAddMethod(attr, initial):
def addMethod(self):
- setattr(self, attr, eval(initial, globals().update(classes)))
+ setattr(self, attr, initial())
return addMethod
def generateDeleteMethod(attr):
@@ -806,6 +911,12 @@
getattr(self, attr).insert(index, value)
return insertMethod
+def generateAppendChoiceByTypeMethod(choice_type, initial_values):
+ def addChoiceMethod(self, name):
+ if name in choice_type:
+ self.content.append({"name" : name, "value" : initial_values[name]()})
+ return addChoiceMethod
+
def generateAppendChoiceMethod(choice_types):
def appendMethod(self, name, value):
self.content.append({"name":name,"value":value})
@@ -836,6 +947,7 @@
sys._getframe(1).f_locals[ClassName] = Class
for TypeName, Type in pluginTypes.items():
sys._getframe(1).f_locals[TypeName] = Type
+ globals().update(ComputedClasses)
return ComputedClasses, ComputedTypes
"""
@@ -854,4 +966,3 @@
factory = ClassFactory(minidom.parseString(xsdstring))
return GenerateClasses(factory, declare)
-