42 if name is not None: |
42 if name is not None: |
43 text += "</%s>\n" % name |
43 text += "</%s>\n" % name |
44 return text |
44 return text |
45 return generateXMLTextMethod |
45 return generateXMLTextMethod |
46 |
46 |
47 def GenerateFloatXMLText(extra_values=[]): |
47 def GenerateFloatXMLText(extra_values=[], decimal=None): |
|
48 float_format = (lambda x: "{:.{width}f}".format(x, width=decimal).rstrip('0') |
|
49 if decimal is not None else str) |
48 def generateXMLTextMethod(value, name=None, indent=0): |
50 def generateXMLTextMethod(value, name=None, indent=0): |
49 text = "" |
51 text = "" |
50 if name is not None: |
52 if name is not None: |
51 ind1, ind2 = getIndent(indent, name) |
53 ind1, ind2 = getIndent(indent, name) |
52 text += ind1 + "<%s>" % name |
54 text += ind1 + "<%s>" % name |
53 if value in extra_values or value % 1 != 0 or isinstance(value, IntType): |
55 if isinstance(value, IntType): |
54 text += str(value) |
56 text += str(value) |
|
57 elif value in extra_values or value % 1 != 0: |
|
58 text += float_format(value) |
55 else: |
59 else: |
56 text += "%.0f" % value |
60 text += "{:.0f}".format(value) |
57 if name is not None: |
61 if name is not None: |
58 text += "</%s>\n" % name |
62 text += "</%s>\n" % name |
59 return text |
63 return text |
60 return generateXMLTextMethod |
64 return generateXMLTextMethod |
61 |
65 |
922 if factory.TargetNamespace == include_factory.TargetNamespace: |
926 if factory.TargetNamespace == include_factory.TargetNamespace: |
923 factory.Namespaces[factory.TargetNamespace].update(include_factory.Namespaces[include_factory.TargetNamespace]) |
927 factory.Namespaces[factory.TargetNamespace].update(include_factory.Namespaces[include_factory.TargetNamespace]) |
924 else: |
928 else: |
925 factory.Namespaces[include_factory.TargetNamespace] = include_factory.Namespaces[include_factory.TargetNamespace] |
929 factory.Namespaces[include_factory.TargetNamespace] = include_factory.Namespaces[include_factory.TargetNamespace] |
926 factory.ComputedClasses.update(include_factory.ComputedClasses) |
930 factory.ComputedClasses.update(include_factory.ComputedClasses) |
|
931 factory.ComputedClassesLookUp.update(include_factory.ComputedClassesLookUp) |
|
932 factory.EquivalentClassesParent.update(include_factory.EquivalentClassesParent) |
927 return None |
933 return None |
928 |
934 |
929 def ReduceRedefine(factory, attributes, elements): |
935 def ReduceRedefine(factory, attributes, elements): |
930 annotations, children = factory.ReduceElements(elements) |
936 annotations, children = factory.ReduceElements(elements) |
931 raise ValueError("\"redefine\" element isn't supported yet!") |
937 raise ValueError("\"redefine\" element isn't supported yet!") |
937 factory.AttributeFormDefault = attributes["attributeFormDefault"] |
943 factory.AttributeFormDefault = attributes["attributeFormDefault"] |
938 factory.ElementFormDefault = attributes["elementFormDefault"] |
944 factory.ElementFormDefault = attributes["elementFormDefault"] |
939 factory.BlockDefault = attributes["blockDefault"] |
945 factory.BlockDefault = attributes["blockDefault"] |
940 factory.FinalDefault = attributes["finalDefault"] |
946 factory.FinalDefault = attributes["finalDefault"] |
941 |
947 |
942 if attributes.has_key("targetNamespace"): |
948 targetNamespace = attributes.get("targetNamespace", None) |
943 factory.TargetNamespace = factory.DefinedNamespaces.get(attributes["targetNamespace"], None) |
949 factory.TargetNamespace = factory.DefinedNamespaces.get(targetNamespace, None) |
|
950 if factory.TargetNamespace is not None: |
|
951 factory.etreeNamespaceFormat = "{%s}%%s" % targetNamespace |
944 factory.Namespaces[factory.TargetNamespace] = {} |
952 factory.Namespaces[factory.TargetNamespace] = {} |
945 |
953 |
946 annotations, children = factory.ReduceElements(elements, True) |
954 annotations, children = factory.ReduceElements(elements, True) |
947 |
955 |
948 for child in children: |
956 for child in children: |
1028 for child in self.Document.childNodes: |
1036 for child in self.Document.childNodes: |
1029 if child.nodeType == self.Document.ELEMENT_NODE: |
1037 if child.nodeType == self.Document.ELEMENT_NODE: |
1030 schema = child |
1038 schema = child |
1031 break |
1039 break |
1032 for qualified_name, attr in schema._attrs.items(): |
1040 for qualified_name, attr in schema._attrs.items(): |
1033 value = GetAttributeValue(attr) |
1041 namespace, name = DecomposeQualifiedName(qualified_name) |
1034 if value == "http://www.w3.org/2001/XMLSchema": |
1042 if namespace == "xmlns": |
1035 namespace, name = DecomposeQualifiedName(qualified_name) |
1043 value = GetAttributeValue(attr) |
1036 if namespace == "xmlns": |
1044 self.DefinedNamespaces[value] = name |
1037 self.DefinedNamespaces["http://www.w3.org/2001/XMLSchema"] = name |
1045 self.NSMAP[name] = value |
|
1046 if value == "http://www.w3.org/2001/XMLSchema": |
1038 self.SchemaNamespace = name |
1047 self.SchemaNamespace = name |
1039 else: |
1048 self.Namespaces[self.SchemaNamespace] = XSD_NAMESPACE |
1040 self.DefinedNamespaces["http://www.w3.org/2001/XMLSchema"] = self.SchemaNamespace |
|
1041 self.Namespaces[self.SchemaNamespace] = XSD_NAMESPACE |
|
1042 self.Schema = XSD_NAMESPACE["schema"]["extract"]["default"](self, schema) |
1049 self.Schema = XSD_NAMESPACE["schema"]["extract"]["default"](self, schema) |
1043 ReduceSchema(self, self.Schema[1], self.Schema[2]) |
1050 ReduceSchema(self, self.Schema[1], self.Schema[2]) |
1044 |
1051 |
1045 def FindSchemaElement(self, element_name, element_type=None): |
1052 def FindSchemaElement(self, element_name, element_type=None): |
1046 namespace, name = DecomposeQualifiedName(element_name) |
1053 namespace, name = DecomposeQualifiedName(element_name) |
1082 self.Namespaces[self.TargetNamespace][element_name] = element_infos |
1089 self.Namespaces[self.TargetNamespace][element_name] = element_infos |
1083 return element_infos |
1090 return element_infos |
1084 return None |
1091 return None |
1085 |
1092 |
1086 """ |
1093 """ |
1087 This function opens the xsd file and generate the classes from the xml tree |
1094 This function opens the xsd file and generate a xml parser with class lookup from |
|
1095 the xml tree |
1088 """ |
1096 """ |
1089 def GenerateClassesFromXSD(filepath): |
1097 def GenerateParserFromXSD(filepath): |
1090 xsdfile = open(filepath, 'r') |
1098 xsdfile = open(filepath, 'r') |
1091 factory = XSDClassFactory(minidom.parse(xsdfile), filepath) |
1099 xsdstring = xsdfile.read() |
1092 xsdfile.close() |
1100 xsdfile.close() |
1093 return GenerateClasses(factory) |
1101 cwd = os.getcwd() |
|
1102 os.chdir(os.path.dirname(filepath)) |
|
1103 parser = GenerateParser(XSDClassFactory(minidom.parseString(xsdstring), filepath), xsdstring) |
|
1104 os.chdir(cwd) |
|
1105 return parser |
1094 |
1106 |
1095 """ |
1107 """ |
1096 This function generate the classes from the xsd given as a string |
1108 This function generate a xml from the xsd given as a string |
1097 """ |
1109 """ |
1098 def GenerateClassesFromXSDstring(xsdstring): |
1110 def GenerateParserFromXSDstring(xsdstring): |
1099 return GenerateClasses(XSDClassFactory(minidom.parseString(xsdstring))) |
1111 return GenerateParser(XSDClassFactory(minidom.parseString(xsdstring)), xsdstring) |
1100 |
1112 |
1101 |
1113 |
1102 #------------------------------------------------------------------------------- |
1114 #------------------------------------------------------------------------------- |
1103 # XSD schema syntax elements |
1115 # XSD schema syntax elements |
1104 #------------------------------------------------------------------------------- |
1116 #------------------------------------------------------------------------------- |
2259 "decimal": { |
2271 "decimal": { |
2260 "type": SIMPLETYPE, |
2272 "type": SIMPLETYPE, |
2261 "basename": "decimal", |
2273 "basename": "decimal", |
2262 "extract": GenerateFloatExtraction("decimal"), |
2274 "extract": GenerateFloatExtraction("decimal"), |
2263 "facets": DECIMAL_FACETS, |
2275 "facets": DECIMAL_FACETS, |
2264 "generate": GenerateFloatXMLText(), |
2276 "generate": GenerateFloatXMLText(decimal=3), |
2265 "initial": lambda: 0., |
2277 "initial": lambda: 0., |
2266 "check": lambda x: isinstance(x, (IntType, FloatType)) |
2278 "check": lambda x: isinstance(x, (IntType, FloatType)) |
2267 }, |
2279 }, |
2268 |
2280 |
2269 "float": { |
2281 "float": { |
2518 |
2530 |
2519 # Complex Types |
2531 # Complex Types |
2520 "anyType": {"type": COMPLEXTYPE, "extract": lambda x:None}, |
2532 "anyType": {"type": COMPLEXTYPE, "extract": lambda x:None}, |
2521 } |
2533 } |
2522 |
2534 |
2523 if __name__ == '__main__': |
|
2524 classes = GenerateClassesFromXSD("test.xsd") |
|
2525 |
|
2526 # Code for test of test.xsd |
|
2527 xmlfile = open("po.xml", 'r') |
|
2528 tree = minidom.parse(xmlfile) |
|
2529 xmlfile.close() |
|
2530 test = classes["PurchaseOrderType"]() |
|
2531 for child in tree.childNodes: |
|
2532 if child.nodeType == tree.ELEMENT_NODE and child.nodeName == "purchaseOrder": |
|
2533 test.loadXMLTree(child) |
|
2534 test.items.item[0].setquantity(2) |
|
2535 testfile = open("test.xml", 'w') |
|
2536 testfile.write(u'<?xml version=\"1.0\"?>\n') |
|
2537 testfile.write(test.generateXMLText("purchaseOrder").encode("utf-8")) |
|
2538 testfile.close() |
|