1061 else: |
1080 else: |
1062 raise ValueError("\"%s\" class already defined. Choose another name!" % typename) |
1081 raise ValueError("\"%s\" class already defined. Choose another name!" % typename) |
1063 |
1082 |
1064 def ParseSchema(self): |
1083 def ParseSchema(self): |
1065 pass |
1084 pass |
1066 |
1085 |
|
1086 def AddEquivalentClass(self, name, base): |
|
1087 equivalences = self.EquivalentClassesParent.setdefault(self.etreeNamespaceFormat % name, {}) |
|
1088 equivalences[self.etreeNamespaceFormat % base] = True |
|
1089 |
|
1090 def AddToLookupClass(self, name, parent, typeinfos): |
|
1091 lookup_name = self.etreeNamespaceFormat % name |
|
1092 if isinstance(typeinfos, (StringType, UnicodeType)): |
|
1093 self.AddEquivalentClass(name, typeinfos) |
|
1094 typeinfos = self.etreeNamespaceFormat % typeinfos |
|
1095 lookup_classes = self.ComputedClassesLookUp.get(lookup_name) |
|
1096 if lookup_classes is None: |
|
1097 self.ComputedClassesLookUp[lookup_name] = (typeinfos, parent) |
|
1098 elif isinstance(lookup_classes, DictType): |
|
1099 lookup_classes[self.etreeNamespaceFormat % parent |
|
1100 if parent is not None else None] = typeinfos |
|
1101 else: |
|
1102 lookup_classes = {self.etreeNamespaceFormat % lookup_classes[1] |
|
1103 if lookup_classes[1] is not None else None: lookup_classes[0]} |
|
1104 lookup_classes[self.etreeNamespaceFormat % parent |
|
1105 if parent is not None else None] = typeinfos |
|
1106 self.ComputedClassesLookUp[lookup_name] = lookup_classes |
|
1107 |
1067 def ExtractTypeInfos(self, name, parent, typeinfos): |
1108 def ExtractTypeInfos(self, name, parent, typeinfos): |
1068 if isinstance(typeinfos, (StringType, UnicodeType)): |
1109 if isinstance(typeinfos, (StringType, UnicodeType)): |
1069 namespace, name = DecomposeQualifiedName(typeinfos) |
1110 namespace, type_name = DecomposeQualifiedName(typeinfos) |
1070 infos = self.GetQualifiedNameInfos(name, namespace) |
1111 if namespace == self.TargetNamespace and name != "base": |
|
1112 self.AddToLookupClass(name, parent, type_name) |
|
1113 infos = self.GetQualifiedNameInfos(type_name, namespace) |
1071 if infos["type"] == COMPLEXTYPE: |
1114 if infos["type"] == COMPLEXTYPE: |
1072 name, parent = self.SplitQualifiedName(name, namespace) |
1115 type_name, parent = self.SplitQualifiedName(type_name, namespace) |
1073 result = self.CreateClass(name, parent, infos) |
1116 result = self.CreateClass(type_name, parent, infos) |
1074 if result is not None and not isinstance(result, (UnicodeType, StringType)): |
1117 if result is not None and not isinstance(result, (UnicodeType, StringType)): |
1075 self.Namespaces[self.TargetNamespace][result["name"]] = result |
1118 self.Namespaces[self.TargetNamespace][result["name"]] = result |
1076 return result |
1119 return result |
1077 elif infos["type"] == ELEMENT and infos["elmt_type"]["type"] == COMPLEXTYPE: |
1120 elif infos["type"] == ELEMENT and infos["elmt_type"]["type"] == COMPLEXTYPE: |
1078 name, parent = self.SplitQualifiedName(name, namespace) |
1121 type_name, parent = self.SplitQualifiedName(type_name, namespace) |
1079 result = self.CreateClass(name, parent, infos["elmt_type"]) |
1122 result = self.CreateClass(type_name, parent, infos["elmt_type"]) |
1080 if result is not None and not isinstance(result, (UnicodeType, StringType)): |
1123 if result is not None and not isinstance(result, (UnicodeType, StringType)): |
1081 self.Namespaces[self.TargetNamespace][result["name"]] = result |
1124 self.Namespaces[self.TargetNamespace][result["name"]] = result |
1082 return result |
1125 return result |
1083 else: |
1126 else: |
1084 return infos |
1127 return infos |
1210 else: |
1253 else: |
1211 infos = self.ExtractTypeInfos(element["name"], name, element["elmt_type"]) |
1254 infos = self.ExtractTypeInfos(element["name"], name, element["elmt_type"]) |
1212 if infos is not None: |
1255 if infos is not None: |
1213 element["elmt_type"] = infos |
1256 element["elmt_type"] = infos |
1214 if element["maxOccurs"] == "unbounded" or element["maxOccurs"] > 1: |
1257 if element["maxOccurs"] == "unbounded" or element["maxOccurs"] > 1: |
1215 classmembers[elmtname] = [] |
|
1216 classmembers["append%s" % elmtname] = generateAppendMethod(elmtname, element["maxOccurs"], self, element) |
1258 classmembers["append%s" % elmtname] = generateAppendMethod(elmtname, element["maxOccurs"], self, element) |
1217 classmembers["insert%s" % elmtname] = generateInsertMethod(elmtname, element["maxOccurs"], self, element) |
1259 classmembers["insert%s" % elmtname] = generateInsertMethod(elmtname, element["maxOccurs"], self, element) |
1218 classmembers["remove%s" % elmtname] = generateRemoveMethod(elmtname, element["minOccurs"]) |
1260 classmembers["remove%s" % elmtname] = generateRemoveMethod(elmtname, element["minOccurs"]) |
1219 classmembers["count%s" % elmtname] = generateCountMethod(elmtname) |
1261 classmembers["count%s" % elmtname] = generateCountMethod(elmtname) |
1220 else: |
1262 else: |
1221 if element["minOccurs"] == 0: |
1263 if element["minOccurs"] == 0: |
1222 classmembers[elmtname] = None |
|
1223 classmembers["add%s" % elmtname] = generateAddMethod(elmtname, self, element) |
1264 classmembers["add%s" % elmtname] = generateAddMethod(elmtname, self, element) |
1224 classmembers["delete%s" % elmtname] = generateDeleteMethod(elmtname) |
1265 classmembers["delete%s" % elmtname] = generateDeleteMethod(elmtname) |
1225 elif not isinstance(element["elmt_type"], (UnicodeType, StringType)): |
|
1226 classmembers[elmtname] = element["elmt_type"]["initial"]() |
|
1227 else: |
|
1228 classmembers[elmtname] = None |
|
1229 classmembers["set%s" % elmtname] = generateSetMethod(elmtname) |
1266 classmembers["set%s" % elmtname] = generateSetMethod(elmtname) |
1230 classmembers["get%s" % elmtname] = generateGetMethod(elmtname) |
1267 classmembers["get%s" % elmtname] = generateGetMethod(elmtname) |
1231 |
1268 |
1232 classmembers["__init__"] = generateInitMethod(self, classinfos) |
1269 classmembers["_init"] = generateInitMethod(self, classinfos) |
1233 classmembers["getStructure"] = generateStructureMethod(classinfos) |
1270 classmembers["getStructure"] = generateStructureMethod(classinfos) |
1234 classmembers["loadXMLTree"] = generateLoadXMLTree(self, classinfos) |
1271 classmembers["loadXMLTree"] = generateLoadXMLTree(self, classinfos) |
1235 classmembers["generateXMLText"] = generateGenerateXMLText(self, classinfos) |
1272 classmembers["generateXMLText"] = generateGenerateXMLText(self, classinfos) |
1236 classmembers["getElementAttributes"] = generateGetElementAttributes(self, classinfos) |
1273 classmembers["getElementAttributes"] = generateGetElementAttributes(self, classinfos) |
1237 classmembers["getElementInfos"] = generateGetElementInfos(self, classinfos) |
1274 classmembers["getElementInfos"] = generateGetElementInfos(self, classinfos) |
1304 instance = class_definition() |
1345 instance = class_definition() |
1305 instance.loadXMLTree(node) |
1346 instance.loadXMLTree(node) |
1306 return instance |
1347 return instance |
1307 return classExtractfunction |
1348 return classExtractfunction |
1308 |
1349 |
|
1350 def generateGetattrMethod(factory, class_definition, classinfos): |
|
1351 attributes = dict([(attr["name"], attr) for attr in classinfos["attributes"] if attr["use"] != "prohibited"]) |
|
1352 optional_attributes = dict([(attr["name"], True) for attr in classinfos["attributes"] if attr["use"] == "optional"]) |
|
1353 elements = dict([(element["name"], element) for element in classinfos["elements"]]) |
|
1354 |
|
1355 def getattrMethod(self, name): |
|
1356 if attributes.has_key(name): |
|
1357 attribute_infos = attributes[name] |
|
1358 attribute_infos["attr_type"] = FindTypeInfos(factory, attribute_infos["attr_type"]) |
|
1359 value = self.get(name) |
|
1360 if value is not None: |
|
1361 return attribute_infos["attr_type"]["extract"](value, extract=False) |
|
1362 elif attribute_infos.has_key("fixed"): |
|
1363 return attribute_infos["attr_type"]["extract"](attribute_infos["fixed"], extract=False) |
|
1364 return attribute_infos["attr_type"]["initial"]() |
|
1365 |
|
1366 elif elements.has_key(name): |
|
1367 element_infos = elements[name] |
|
1368 element_infos["elmt_type"] = FindTypeInfos(factory, element_infos["elmt_type"]) |
|
1369 if name == "content": |
|
1370 content = self.xpath(element_infos["elmt_type"]["choices_xpath"](), namespaces=factory.NSMAP) |
|
1371 if element_infos["maxOccurs"] == "unbounded" or element_infos["maxOccurs"] > 1: |
|
1372 return content |
|
1373 elif len(content) > 0: |
|
1374 return content[0] |
|
1375 return None |
|
1376 else: |
|
1377 element_name = factory.etreeNamespaceFormat % name |
|
1378 if element_infos["maxOccurs"] == "unbounded" or element_infos["maxOccurs"] > 1: |
|
1379 return self.findall(element_name) |
|
1380 else: |
|
1381 return self.find(element_name) |
|
1382 |
|
1383 elif classinfos.has_key("base"): |
|
1384 return classinfos["base"].__getattr__(self, name) |
|
1385 |
|
1386 return DefaultElementClass.__getattribute__(self, name) |
|
1387 |
|
1388 return getattrMethod |
|
1389 |
1309 """ |
1390 """ |
1310 Method that generate the method for loading an xml tree by following the |
1391 Method that generate the method for loading an xml tree by following the |
1311 attributes list defined |
1392 attributes list defined |
1312 """ |
1393 """ |
1313 def generateSetattrMethod(factory, class_definition, classinfos): |
1394 def generateSetattrMethod(factory, class_definition, classinfos): |
1314 attributes = dict([(attr["name"], attr) for attr in classinfos["attributes"] if attr["use"] != "prohibited"]) |
1395 attributes = dict([(attr["name"], attr) for attr in classinfos["attributes"] if attr["use"] != "prohibited"]) |
1315 optional_attributes = dict([(attr["name"], True) for attr in classinfos["attributes"] if attr["use"] == "optional"]) |
1396 optional_attributes = dict([(attr["name"], True) for attr in classinfos["attributes"] if attr["use"] == "optional"]) |
1316 elements = dict([(element["name"], element) for element in classinfos["elements"]]) |
1397 elements = OrderedDict([(element["name"], element) for element in classinfos["elements"]]) |
1317 |
1398 |
1318 def setattrMethod(self, name, value): |
1399 def setattrMethod(self, name, value): |
1319 if attributes.has_key(name): |
1400 if attributes.has_key(name): |
1320 attributes[name]["attr_type"] = FindTypeInfos(factory, attributes[name]["attr_type"]) |
1401 attribute_infos = attributes[name] |
1321 if value is None: |
1402 attribute_infos["attr_type"] = FindTypeInfos(factory, attribute_infos["attr_type"]) |
1322 if optional_attributes.get(name, False): |
1403 if optional_attributes.get(name, False): |
1323 return object.__setattr__(self, name, None) |
1404 default = attribute_infos.get("default", None) |
1324 else: |
1405 if value is None or value == default: |
1325 raise ValueError("Attribute '%s' isn't optional." % name) |
1406 self.attrib.pop(name) |
1326 elif attributes[name].has_key("fixed") and value != attributes[name]["fixed"]: |
1407 return |
1327 raise ValueError, "Value of attribute '%s' can only be '%s'."%(name, str(attributes[name]["fixed"])) |
1408 elif attribute_infos.has_key("fixed"): |
1328 elif attributes[name]["attr_type"]["check"](value): |
1409 return |
1329 return object.__setattr__(self, name, value) |
1410 return self.set(name, attribute_infos["attr_type"]["generate"](value)) |
1330 else: |
1411 |
1331 raise ValueError("Invalid value for attribute '%s'." % (name)) |
|
1332 elif elements.has_key(name): |
1412 elif elements.has_key(name): |
1333 if CheckElementValue(factory, name, elements[name], value): |
1413 element_infos = elements[name] |
1334 return object.__setattr__(self, name, value) |
1414 element_infos["elmt_type"] = FindTypeInfos(factory, element_infos["elmt_type"]) |
1335 else: |
1415 element_xpath = ("%s:%s" % (factory.TargetNamespace, name) |
1336 raise ValueError("Invalid value for attribute '%s'." % (name)) |
1416 if name != "content" |
|
1417 else elements["content"]["elmt_type"]["choices_xpath"]()) |
|
1418 |
|
1419 for element in self.xpath(element_xpath, namespaces=factory.NSMAP): |
|
1420 self.remove(element) |
|
1421 |
|
1422 if value is not None: |
|
1423 previous_elements_xpath = "|".join(map( |
|
1424 lambda x: "%s:%s" % (factory.TargetNamespace, x) |
|
1425 if x != "content" |
|
1426 else elements["content"]["elmt_type"]["choices_xpath"](), |
|
1427 elements.keys()[elements.keys().index(name)])) |
|
1428 |
|
1429 insertion_point = len(self.xpath(previous_elements_xpath, namespaces=factory.NSMAP)) |
|
1430 |
|
1431 if not isinstance(value, ListType): |
|
1432 value = [value] |
|
1433 |
|
1434 for element in reversed(value): |
|
1435 self.insert(insertion_point, element) |
|
1436 |
1337 elif classinfos.has_key("base"): |
1437 elif classinfos.has_key("base"): |
1338 return classinfos["base"].__setattr__(self, name, value) |
1438 return classinfos["base"].__setattr__(self, name, value) |
|
1439 |
1339 elif class_definition.__dict__.has_key(name): |
1440 elif class_definition.__dict__.has_key(name): |
1340 return object.__setattr__(self, name, value) |
1441 return DefaultElementClass.__setattr__(self, name, value) |
|
1442 |
1341 else: |
1443 else: |
1342 raise AttributeError("'%s' can't have an attribute '%s'." % (self.__class__.__name__, name)) |
1444 raise AttributeError("'%s' can't have an attribute '%s'." % (self.__class__.__name__, name)) |
1343 |
1445 |
1344 return setattrMethod |
1446 return setattrMethod |
1345 |
1447 |
1723 """ |
1825 """ |
1724 def generateInitMethod(factory, classinfos): |
1826 def generateInitMethod(factory, classinfos): |
1725 def initMethod(self): |
1827 def initMethod(self): |
1726 self.extraAttrs = {} |
1828 self.extraAttrs = {} |
1727 if classinfos.has_key("base"): |
1829 if classinfos.has_key("base"): |
1728 classinfos["base"].__init__(self) |
1830 classinfos["base"]._init(self) |
1729 for attribute in classinfos["attributes"]: |
1831 for attribute in classinfos["attributes"]: |
1730 attribute["attr_type"] = FindTypeInfos(factory, attribute["attr_type"]) |
1832 attribute["attr_type"] = FindTypeInfos(factory, attribute["attr_type"]) |
1731 if attribute["use"] == "required": |
1833 if attribute["use"] == "required" and self.get(attribute["name"]) is None: |
1732 setattr(self, attribute["name"], attribute["attr_type"]["initial"]()) |
1834 self.set(attribute["name"], attribute["attr_type"]["generate"](attribute["attr_type"]["initial"]())) |
1733 elif attribute["use"] == "optional": |
|
1734 if attribute.has_key("default"): |
|
1735 setattr(self, attribute["name"], attribute["attr_type"]["extract"](attribute["default"], False)) |
|
1736 else: |
|
1737 setattr(self, attribute["name"], None) |
|
1738 for element in classinfos["elements"]: |
1835 for element in classinfos["elements"]: |
1739 setattr(self, element["name"], GetElementInitialValue(factory, element)) |
1836 if element["name"] != "content": |
|
1837 element_name = ( |
|
1838 etree.QName(factory.NSMAP["xhtml"], "p") |
|
1839 if element["type"] == ANY |
|
1840 else factory.etreeNamespaceFormat % element["name"]) |
|
1841 if self.find(element_name) is None: |
|
1842 initial = GetElementInitialValue(factory, element) |
|
1843 if initial is not None: |
|
1844 map(self.append, initial) |
1740 return initMethod |
1845 return initMethod |
1741 |
1846 |
1742 def generateSetMethod(attr): |
1847 def generateSetMethod(attr): |
1743 def setMethod(self, value): |
1848 def setMethod(self, value): |
1744 setattr(self, attr, value) |
1849 setattr(self, attr, value) |
1775 def generateAppendMethod(attr, maxOccurs, factory, infos): |
1878 def generateAppendMethod(attr, maxOccurs, factory, infos): |
1776 def appendMethod(self, value): |
1879 def appendMethod(self, value): |
1777 infos["elmt_type"] = FindTypeInfos(factory, infos["elmt_type"]) |
1880 infos["elmt_type"] = FindTypeInfos(factory, infos["elmt_type"]) |
1778 attr_list = getattr(self, attr) |
1881 attr_list = getattr(self, attr) |
1779 if maxOccurs == "unbounded" or len(attr_list) < maxOccurs: |
1882 if maxOccurs == "unbounded" or len(attr_list) < maxOccurs: |
1780 if infos["elmt_type"]["check"](value): |
1883 if len(attr_list) == 0: |
1781 attr_list.append(value) |
1884 setattr(self, attr, [value]) |
1782 else: |
1885 else: |
1783 raise ValueError("\"%s\" value isn't valid!" % attr) |
1886 attr_list[-1].addnext(value) |
1784 else: |
1887 else: |
1785 raise ValueError("There can't be more than %d values in \"%s\"!" % (maxOccurs, attr)) |
1888 raise ValueError("There can't be more than %d values in \"%s\"!" % (maxOccurs, attr)) |
1786 return appendMethod |
1889 return appendMethod |
1787 |
1890 |
1788 def generateInsertMethod(attr, maxOccurs, factory, infos): |
1891 def generateInsertMethod(attr, maxOccurs, factory, infos): |
1789 def insertMethod(self, index, value): |
1892 def insertMethod(self, index, value): |
1790 infos["elmt_type"] = FindTypeInfos(factory, infos["elmt_type"]) |
1893 infos["elmt_type"] = FindTypeInfos(factory, infos["elmt_type"]) |
1791 attr_list = getattr(self, attr) |
1894 attr_list = getattr(self, attr) |
1792 if maxOccurs == "unbounded" or len(attr_list) < maxOccurs: |
1895 if maxOccurs == "unbounded" or len(attr_list) < maxOccurs: |
1793 if infos["elmt_type"]["check"](value): |
1896 if len(attr_list) == 0: |
1794 attr_list.insert(index, value) |
1897 setattr(self, attr, [value]) |
|
1898 elif index == 0: |
|
1899 attr_list[0].addprevious(value) |
1795 else: |
1900 else: |
1796 raise ValueError("\"%s\" value isn't valid!" % attr) |
1901 attr_list[min(index - 1, len(attr_list) - 1)].addnext(value) |
1797 else: |
1902 else: |
1798 raise ValueError("There can't be more than %d values in \"%s\"!" % (maxOccurs, attr)) |
1903 raise ValueError("There can't be more than %d values in \"%s\"!" % (maxOccurs, attr)) |
1799 return insertMethod |
1904 return insertMethod |
1800 |
1905 |
1801 def generateGetChoicesMethod(choice_types): |
1906 def generateGetChoicesMethod(choice_types): |
1803 return [choice["name"] for choice in choice_types] |
1908 return [choice["name"] for choice in choice_types] |
1804 return getChoicesMethod |
1909 return getChoicesMethod |
1805 |
1910 |
1806 def generateSetChoiceByTypeMethod(factory, choice_types): |
1911 def generateSetChoiceByTypeMethod(factory, choice_types): |
1807 choices = dict([(choice["name"], choice) for choice in choice_types]) |
1912 choices = dict([(choice["name"], choice) for choice in choice_types]) |
1808 def setChoiceMethod(self, type): |
1913 def setChoiceMethod(self, content_type): |
1809 if not choices.has_key(type): |
1914 if not choices.has_key(content_type): |
1810 raise ValueError("Unknown \"%s\" choice type for \"content\"!" % type) |
1915 raise ValueError("Unknown \"%s\" choice type for \"content\"!" % content_type) |
1811 choices[type]["elmt_type"] = FindTypeInfos(factory, choices[type]["elmt_type"]) |
1916 choices[content_type]["elmt_type"] = FindTypeInfos(factory, choices[content_type]["elmt_type"]) |
1812 new_element = choices[type]["elmt_type"]["initial"]() |
1917 new_content = choices[content_type]["elmt_type"]["initial"]() |
1813 self.content = {"name": type, "value": new_element} |
1918 self.content = new_content |
1814 return new_element |
1919 return new_content |
1815 return setChoiceMethod |
1920 return setChoiceMethod |
1816 |
1921 |
1817 def generateAppendChoiceByTypeMethod(maxOccurs, factory, choice_types): |
1922 def generateAppendChoiceByTypeMethod(maxOccurs, factory, choice_types): |
1818 choices = dict([(choice["name"], choice) for choice in choice_types]) |
1923 choices = dict([(choice["name"], choice) for choice in choice_types]) |
1819 def appendChoiceMethod(self, type): |
1924 def appendChoiceMethod(self, content_type): |
1820 if not choices.has_key(type): |
1925 if not choices.has_key(content_type): |
1821 raise ValueError("Unknown \"%s\" choice type for \"content\"!" % type) |
1926 raise ValueError("Unknown \"%s\" choice type for \"content\"!" % content_type) |
1822 choices[type]["elmt_type"] = FindTypeInfos(factory, choices[type]["elmt_type"]) |
1927 choices[content_type]["elmt_type"] = FindTypeInfos(factory, choices[content_type]["elmt_type"]) |
1823 if maxOccurs == "unbounded" or len(self.content) < maxOccurs: |
1928 if maxOccurs == "unbounded" or len(self.content) < maxOccurs: |
1824 new_element = choices[type]["elmt_type"]["initial"]() |
1929 new_element = choices[content_type]["elmt_type"]["initial"]() |
1825 self.content.append({"name": type, "value": new_element}) |
1930 self.appendcontent(new_element) |
1826 return new_element |
1931 return new_element |
1827 else: |
1932 else: |
1828 raise ValueError("There can't be more than %d values in \"content\"!" % maxOccurs) |
1933 raise ValueError("There can't be more than %d values in \"content\"!" % maxOccurs) |
1829 return appendChoiceMethod |
1934 return appendChoiceMethod |
1830 |
1935 |
1831 def generateInsertChoiceByTypeMethod(maxOccurs, factory, choice_types): |
1936 def generateInsertChoiceByTypeMethod(maxOccurs, factory, choice_types): |
1832 choices = dict([(choice["name"], choice) for choice in choice_types]) |
1937 choices = dict([(choice["name"], choice) for choice in choice_types]) |
1833 def insertChoiceMethod(self, index, type): |
1938 def insertChoiceMethod(self, index, content_type): |
1834 if not choices.has_key(type): |
1939 if not choices.has_key(content_type): |
1835 raise ValueError("Unknown \"%s\" choice type for \"content\"!" % type) |
1940 raise ValueError("Unknown \"%s\" choice type for \"content\"!" % content_type) |
1836 choices[type]["elmt_type"] = FindTypeInfos(factory, choices[type]["elmt_type"]) |
1941 choices[type]["elmt_type"] = FindTypeInfos(factory, choices[content_type]["elmt_type"]) |
1837 if maxOccurs == "unbounded" or len(self.content) < maxOccurs: |
1942 if maxOccurs == "unbounded" or len(self.content) < maxOccurs: |
1838 new_element = choices[type]["elmt_type"]["initial"]() |
1943 new_element = choices[content_type]["elmt_type"]["initial"]() |
1839 self.content.insert(index, {"name" : type, "value" : new_element}) |
1944 self.insertcontent(index, new_element) |
1840 return new_element |
1945 return new_element |
1841 else: |
1946 else: |
1842 raise ValueError("There can't be more than %d values in \"content\"!" % maxOccurs) |
1947 raise ValueError("There can't be more than %d values in \"content\"!" % maxOccurs) |
1843 return insertChoiceMethod |
1948 return insertChoiceMethod |
1844 |
1949 |
1845 def generateRemoveMethod(attr, minOccurs): |
1950 def generateRemoveMethod(attr, minOccurs): |
1846 def removeMethod(self, index): |
1951 def removeMethod(self, index): |
1847 attr_list = getattr(self, attr) |
1952 attr_list = getattr(self, attr) |
1848 if len(attr_list) > minOccurs: |
1953 if len(attr_list) > minOccurs: |
1849 getattr(self, attr).pop(index) |
1954 self.remove(attr_list[index]) |
1850 else: |
1955 else: |
1851 raise ValueError("There can't be less than %d values in \"%s\"!" % (minOccurs, attr)) |
1956 raise ValueError("There can't be less than %d values in \"%s\"!" % (minOccurs, attr)) |
1852 return removeMethod |
1957 return removeMethod |
1853 |
1958 |
1854 def generateCountMethod(attr): |
1959 def generateCountMethod(attr): |
1855 def countMethod(self): |
1960 def countMethod(self): |
1856 return len(getattr(self, attr)) |
1961 return len(getattr(self, attr)) |
1857 return countMethod |
1962 return countMethod |
1858 |
1963 |
1859 """ |
1964 """ |
1860 This function generate the classes from a class factory |
1965 This function generate a xml parser from a class factory |
1861 """ |
1966 """ |
1862 def GenerateClasses(factory): |
1967 |
|
1968 class DefaultElementClass(etree.ElementBase): |
|
1969 toto = True |
|
1970 |
|
1971 def getLocalTag(self): |
|
1972 return etree.QName(self.tag).localname |
|
1973 |
|
1974 def tostring(self): |
|
1975 return etree.tostring(self, pretty_print=True) |
|
1976 |
|
1977 class XMLElementClassLookUp(etree.PythonElementClassLookup): |
|
1978 |
|
1979 def __init__(self, classes, class_equivalence, *args, **kwargs): |
|
1980 etree.PythonElementClassLookup.__init__(self, *args, **kwargs) |
|
1981 self.LookUpClasses = classes |
|
1982 self.ClassEquivalence = class_equivalence |
|
1983 |
|
1984 def GetElementClass(self, element_tag, parent_tag=None, default=DefaultElementClass): |
|
1985 element_class = self.LookUpClasses.get(element_tag, (default, None)) |
|
1986 if not isinstance(element_class, DictType): |
|
1987 if isinstance(element_class[0], (StringType, UnicodeType)): |
|
1988 return self.GetElementClass(element_class[0], default=default) |
|
1989 return element_class[0] |
|
1990 |
|
1991 element_with_parent_class = element_class.get(parent_tag, default) |
|
1992 if isinstance(element_with_parent_class, (StringType, UnicodeType)): |
|
1993 return self.GetElementClass(element_with_parent_class, default=default) |
|
1994 elif element_with_parent_class == DefaultElementClass: |
|
1995 for equivalent_parent in self.ClassEquivalence.get(parent_tag, {}).keys(): |
|
1996 return self.GetElementClass(element_tag, equivalent_parent, default) |
|
1997 return element_with_parent_class |
|
1998 |
|
1999 def lookup(self, document, element): |
|
2000 parent = element.getparent() |
|
2001 return self.GetElementClass(element.tag, |
|
2002 parent.tag if parent is not None else None) |
|
2003 |
|
2004 class XMLClassParser(etree.XMLParser): |
|
2005 |
|
2006 def __init__(self, namespaces, default_namespace_format, base_class, *args, **kwargs): |
|
2007 etree.XMLParser.__init__(self, *args, **kwargs) |
|
2008 self.DefaultNamespaceFormat = default_namespace_format |
|
2009 self.NSMAP = namespaces |
|
2010 targetNamespace = etree.QName(default_namespace_format % "d").namespace |
|
2011 if targetNamespace is not None: |
|
2012 self.RootNSMAP = { |
|
2013 name if targetNamespace != uri else None: uri |
|
2014 for name, uri in namespaces.iteritems()} |
|
2015 else: |
|
2016 self.RootNSMAP = namespaces |
|
2017 self.BaseClass = base_class |
|
2018 |
|
2019 def set_element_class_lookup(self, class_lookup): |
|
2020 etree.XMLParser.set_element_class_lookup(self, class_lookup) |
|
2021 self.ClassLookup = class_lookup |
|
2022 |
|
2023 def CreateRoot(self): |
|
2024 if self.BaseClass is not None: |
|
2025 return self.makeelement( |
|
2026 self.DefaultNamespaceFormat % self.BaseClass[0], |
|
2027 nsmap=self.RootNSMAP) |
|
2028 return None |
|
2029 |
|
2030 def GetElementClass(self, element_tag, parent_tag=None): |
|
2031 return self.ClassLookup.GetElementClass( |
|
2032 self.DefaultNamespaceFormat % element_tag, |
|
2033 self.DefaultNamespaceFormat % parent_tag |
|
2034 if parent_tag is not None else parent_tag, |
|
2035 None) |
|
2036 |
|
2037 def CreateElement(self, element_tag, parent_tag=None): |
|
2038 new_element = self.GetElementClass(element_tag, parent_tag)() |
|
2039 DefaultElementClass.__setattr__(new_element, "tag", self.DefaultNamespaceFormat % element_tag) |
|
2040 return new_element |
|
2041 |
|
2042 def GenerateParser(factory, xsdstring): |
1863 ComputedClasses = factory.CreateClasses() |
2043 ComputedClasses = factory.CreateClasses() |
1864 if factory.FileName is not None and len(ComputedClasses) == 1: |
2044 if factory.FileName is not None and len(ComputedClasses) == 1: |
1865 UpdateXMLClassGlobals(ComputedClasses[factory.FileName]) |
2045 ComputedClasses = ComputedClasses[factory.FileName] |
1866 return ComputedClasses[factory.FileName] |
2046 BaseClass = [(name, XSDclass) for name, XSDclass in ComputedClasses.items() if XSDclass.IsBaseClass] |
1867 else: |
2047 else: |
1868 UpdateXMLClassGlobals(ComputedClasses) |
2048 BaseClass = [] |
1869 return ComputedClasses |
2049 UpdateXMLClassGlobals(ComputedClasses) |
|
2050 |
|
2051 parser = XMLClassParser( |
|
2052 factory.NSMAP, |
|
2053 factory.etreeNamespaceFormat, |
|
2054 BaseClass[0] if len(BaseClass) == 1 else None, |
|
2055 schema = etree.XMLSchema(etree.fromstring(xsdstring)), |
|
2056 strip_cdata = False, remove_blank_text=True) |
|
2057 class_lookup = XMLElementClassLookUp(factory.ComputedClassesLookUp, factory.EquivalentClassesParent) |
|
2058 parser.set_element_class_lookup(class_lookup) |
|
2059 return parser |
1870 |
2060 |
1871 def UpdateXMLClassGlobals(classes): |
2061 def UpdateXMLClassGlobals(classes): |
1872 globals().update(classes) |
2062 globals().update(classes) |
|
2063 |