xmlclass/xmlclass.py
changeset 1315 ff14a66bbd12
parent 1305 714f1381a09a
child 1322 0a9227f743b3
equal deleted inserted replaced
1314:822d483197ad 1315:ff14a66bbd12
   608         else:
   608         else:
   609             def initial_value():
   609             def initial_value():
   610                 value = infos["elmt_type"]["initial"]()
   610                 value = infos["elmt_type"]["initial"]()
   611                 if infos["type"] != ANY:
   611                 if infos["type"] != ANY:
   612                     DefaultElementClass.__setattr__(value, "tag", element_name)
   612                     DefaultElementClass.__setattr__(value, "tag", element_name)
   613                     value.init()
   613                     value._init_()
   614                 return value
   614                 return value
   615         return [initial_value() for i in xrange(infos["minOccurs"])]
   615         return [initial_value() for i in xrange(infos["minOccurs"])]
   616     else:
   616     else:
   617         return []
   617         return []
   618 
   618 
   662                     choices_dict[element["name"]] = infos
   662                     choices_dict[element["name"]] = infos
   663         else:
   663         else:
   664             if choices_dict.has_key(choice_name):
   664             if choices_dict.has_key(choice_name):
   665                 raise ValueError("'%s' element defined two times in choice" % choice_name)
   665                 raise ValueError("'%s' element defined two times in choice" % choice_name)
   666             choices_dict[choice_name] = infos
   666             choices_dict[choice_name] = infos
   667     choices_xpath = "|".join(map(lambda x: "%s:%s" % (factory.TargetNamespace, x), choices_dict.keys()))
   667     prefix = ("%s:" % factory.TargetNamespace
       
   668               if factory.TargetNamespace is not None else "")
       
   669     choices_xpath = "|".join(map(lambda x: prefix + x, choices_dict.keys()))
   668     
   670     
   669     def GetContentInitial():
   671     def GetContentInitial():
   670         content_name, infos = choices[0]
   672         content_name, infos = choices[0]
   671         if content_name == "sequence":
   673         if content_name == "sequence":
   672             content_value = []
   674             content_value = []
  1125                     classmembers["add%s" % elmtname] = generateAddMethod(elmtname, self, element)
  1127                     classmembers["add%s" % elmtname] = generateAddMethod(elmtname, self, element)
  1126                     classmembers["delete%s" % elmtname] = generateDeleteMethod(elmtname)
  1128                     classmembers["delete%s" % elmtname] = generateDeleteMethod(elmtname)
  1127             classmembers["set%s" % elmtname] = generateSetMethod(elmtname)
  1129             classmembers["set%s" % elmtname] = generateSetMethod(elmtname)
  1128             classmembers["get%s" % elmtname] = generateGetMethod(elmtname)
  1130             classmembers["get%s" % elmtname] = generateGetMethod(elmtname)
  1129             
  1131             
  1130         classmembers["init"] = generateInitMethod(self, classinfos)
  1132         classmembers["_init_"] = generateInitMethod(self, classinfos)
  1131         classmembers["getElementAttributes"] = generateGetElementAttributes(self, classinfos)
  1133         classmembers["getElementAttributes"] = generateGetElementAttributes(self, classinfos)
  1132         classmembers["getElementInfos"] = generateGetElementInfos(self, classinfos)
  1134         classmembers["getElementInfos"] = generateGetElementInfos(self, classinfos)
  1133         classmembers["setElementValue"] = generateSetElementValue(self, classinfos)
  1135         classmembers["setElementValue"] = generateSetElementValue(self, classinfos)
  1134         
  1136         
  1135         class_definition = classobj(str(classname), bases, classmembers)
  1137         class_definition = classobj(str(classname), bases, classmembers)
  1249             element_infos["elmt_type"] = FindTypeInfos(factory, element_infos["elmt_type"])
  1251             element_infos["elmt_type"] = FindTypeInfos(factory, element_infos["elmt_type"])
  1250             if element_infos["type"] == ANY:
  1252             if element_infos["type"] == ANY:
  1251                 element_infos["elmt_type"]["generate"](self, value)
  1253                 element_infos["elmt_type"]["generate"](self, value)
  1252             
  1254             
  1253             else:
  1255             else:
  1254                 element_xpath = ("%s:%s" % (factory.TargetNamespace, name)
  1256                 prefix = ("%s:" % factory.TargetNamespace
       
  1257                           if factory.TargetNamespace is not None else "")
       
  1258                 element_xpath = (prefix + name
  1255                                  if name != "content"
  1259                                  if name != "content"
  1256                                  else elements["content"]["elmt_type"]["choices_xpath"].path)
  1260                                  else elements["content"]["elmt_type"]["choices_xpath"].path)
  1257                 
  1261                 
  1258                 for element in self.xpath(element_xpath, namespaces=factory.NSMAP):
  1262                 for element in self.xpath(element_xpath, namespaces=factory.NSMAP):
  1259                     self.remove(element)
  1263                     self.remove(element)
  1260                 
  1264                 
  1261                 if value is not None:
  1265                 if value is not None:
  1262                     element_idx = elements.keys().index(name)
  1266                     element_idx = elements.keys().index(name)
  1263                     if element_idx > 0:
  1267                     if element_idx > 0:
  1264                         previous_elements_xpath = "|".join(map(
  1268                         previous_elements_xpath = "|".join(map(
  1265                             lambda x: "%s:%s" % (factory.TargetNamespace, x)
  1269                             lambda x: prefix + x
  1266                                       if x != "content"
  1270                                       if x != "content"
  1267                                       else elements["content"]["elmt_type"]["choices_xpath"].path,
  1271                                       else elements["content"]["elmt_type"]["choices_xpath"].path,
  1268                             elements.keys()[:element_idx]))
  1272                             elements.keys()[:element_idx]))
  1269                         
  1273                         
  1270                         insertion_point = len(self.xpath(previous_elements_xpath, namespaces=factory.NSMAP))
  1274                         insertion_point = len(self.xpath(previous_elements_xpath, namespaces=factory.NSMAP))
  1339                         raise ValueError("Wrong path!")
  1343                         raise ValueError("Wrong path!")
  1340                     attr_type = gettypeinfos(elements[parts[0]]["elmt_type"]["basename"], 
  1344                     attr_type = gettypeinfos(elements[parts[0]]["elmt_type"]["basename"], 
  1341                                              elements[parts[0]]["elmt_type"]["facets"])
  1345                                              elements[parts[0]]["elmt_type"]["facets"])
  1342                     value = getattr(self, parts[0], "")
  1346                     value = getattr(self, parts[0], "")
  1343                 elif parts[0] == "content":
  1347                 elif parts[0] == "content":
  1344                     return self.content["value"].getElementInfos(self.content["name"], path)
  1348                     return self.content.getElementInfos(self.content.getLocalTag(), path)
  1345                 else:
  1349                 else:
  1346                     attr = getattr(self, parts[0], None)
  1350                     attr = getattr(self, parts[0], None)
  1347                     if attr is None:
  1351                     if attr is None:
  1348                         raise ValueError("Wrong path!")
  1352                         raise ValueError("Wrong path!")
  1349                     if len(parts) == 1:
  1353                     if len(parts) == 1:
  1350                         return attr.getElementInfos(parts[0])
  1354                         return attr.getElementInfos(parts[0])
  1351                     else:
  1355                     else:
  1352                         return attr.getElementInfos(parts[0], parts[1])
  1356                         return attr.getElementInfos(parts[0], parts[1])
  1353             elif elements.has_key("content"):
  1357             elif elements.has_key("content"):
  1354                 if len(parts) > 0:
  1358                 if len(parts) > 0:
  1355                     return self.content["value"].getElementInfos(name, path)
  1359                     return self.content.getElementInfos(name, path)
  1356             elif classinfos.has_key("base"):
  1360             elif classinfos.has_key("base"):
  1357                 classinfos["base"].getElementInfos(name, path)
  1361                 classinfos["base"].getElementInfos(name, path)
  1358             else:
  1362             else:
  1359                 raise ValueError("Wrong path!")
  1363                 raise ValueError("Wrong path!")
  1360         else:
  1364         else:
  1368                 if element_name == "content" and element["type"] == CHOICE:
  1372                 if element_name == "content" and element["type"] == CHOICE:
  1369                     attr_type = [(choice["name"], None) for choice in element["choices"]]
  1373                     attr_type = [(choice["name"], None) for choice in element["choices"]]
  1370                     if self.content is None:
  1374                     if self.content is None:
  1371                         value = ""
  1375                         value = ""
  1372                     else:
  1376                     else:
  1373                         value = self.content["name"]
  1377                         value = self.content.getLocalTag()
  1374                         if self.content["value"] is not None:
  1378                         if self.content is not None:
  1375                             if self.content["name"] == "sequence":
  1379                             children.extend(self.content.getElementInfos(value)["children"])
  1376                                 choices_dict = dict([(choice["name"], choice) for choice in element["choices"]])
       
  1377                                 sequence_infos = choices_dict.get("sequence", None)
       
  1378                                 if sequence_infos is not None:
       
  1379                                     children.extend([item.getElementInfos(infos["name"]) for item, infos in zip(self.content["value"], sequence_infos["elements"])])
       
  1380                             else:
       
  1381                                 children.extend(self.content["value"].getElementInfos(self.content["name"])["children"])
       
  1382                 elif element["elmt_type"]["type"] == SIMPLETYPE:
  1380                 elif element["elmt_type"]["type"] == SIMPLETYPE:
  1383                     children.append({"name": element_name, "require": element["minOccurs"] != 0, 
  1381                     children.append({"name": element_name, "require": element["minOccurs"] != 0, 
  1384                         "type": gettypeinfos(element["elmt_type"]["basename"], 
  1382                         "type": gettypeinfos(element["elmt_type"]["basename"], 
  1385                                              element["elmt_type"]["facets"]),
  1383                                              element["elmt_type"]["facets"]),
  1386                         "value": getattr(self, element_name, None)})
  1384                         "value": getattr(self, element_name, None)})
  1433                             instance.setElementValue(parts[1], value)
  1431                             instance.setElementValue(parts[1], value)
  1434                         else:
  1432                         else:
  1435                             instance.setElementValue(None, value)
  1433                             instance.setElementValue(None, value)
  1436             elif elements.has_key("content"):
  1434             elif elements.has_key("content"):
  1437                 if len(parts) > 0:
  1435                 if len(parts) > 0:
  1438                     self.content["value"].setElementValue(path, value)
  1436                     self.content.setElementValue(path, value)
  1439             elif classinfos.has_key("base"):
  1437             elif classinfos.has_key("base"):
  1440                 classinfos["base"].setElementValue(self, path, value)
  1438                 classinfos["base"].setElementValue(self, path, value)
  1441         elif elements.has_key("content"):
  1439         elif elements.has_key("content"):
  1442             if value == "":
  1440             if value == "":
  1443                 if elements["content"]["minOccurs"] == 0:
  1441                 if elements["content"]["minOccurs"] == 0:
  1444                     self.setcontent(None)
  1442                     self.setcontent([])
  1445                 else:
  1443                 else:
  1446                     raise ValueError("\"content\" element is required!")
  1444                     raise ValueError("\"content\" element is required!")
  1447             else:
  1445             else:
  1448                 self.setcontentbytype(value)
  1446                 self.setcontentbytype(value)
  1449     return setElementValue
  1447     return setElementValue
  1452 Methods that generates the different methods for setting and getting the attributes
  1450 Methods that generates the different methods for setting and getting the attributes
  1453 """
  1451 """
  1454 def generateInitMethod(factory, classinfos):
  1452 def generateInitMethod(factory, classinfos):
  1455     def initMethod(self):
  1453     def initMethod(self):
  1456         if classinfos.has_key("base"):
  1454         if classinfos.has_key("base"):
  1457             classinfos["base"].init(self)
  1455             classinfos["base"]._init_(self)
  1458         for attribute in classinfos["attributes"]:
  1456         for attribute in classinfos["attributes"]:
  1459             attribute["attr_type"] = FindTypeInfos(factory, attribute["attr_type"])
  1457             attribute["attr_type"] = FindTypeInfos(factory, attribute["attr_type"])
  1460             if attribute["use"] == "required":
  1458             if attribute["use"] == "required":
  1461                 self.set(attribute["name"], attribute["attr_type"]["generate"](attribute["attr_type"]["initial"]()))
  1459                 self.set(attribute["name"], attribute["attr_type"]["generate"](attribute["attr_type"]["initial"]()))
  1462         for element in classinfos["elements"]:
  1460         for element in classinfos["elements"]:
  1489         elif infos["type"] == ELEMENT:
  1487         elif infos["type"] == ELEMENT:
  1490             infos["elmt_type"] = FindTypeInfos(factory, infos["elmt_type"])
  1488             infos["elmt_type"] = FindTypeInfos(factory, infos["elmt_type"])
  1491             value = infos["elmt_type"]["initial"]()
  1489             value = infos["elmt_type"]["initial"]()
  1492             DefaultElementClass.__setattr__(value, "tag", factory.etreeNamespaceFormat % attr)
  1490             DefaultElementClass.__setattr__(value, "tag", factory.etreeNamespaceFormat % attr)
  1493             setattr(self, attr, value)
  1491             setattr(self, attr, value)
  1494             value.init()
  1492             value._init_()
  1495         else:
  1493         else:
  1496             raise ValueError("Invalid class attribute!")
  1494             raise ValueError("Invalid class attribute!")
  1497     return addMethod
  1495     return addMethod
  1498 
  1496 
  1499 def generateDeleteMethod(attr):
  1497 def generateDeleteMethod(attr):
  1539     def setChoiceMethod(self, content_type):
  1537     def setChoiceMethod(self, content_type):
  1540         if not choices.has_key(content_type):
  1538         if not choices.has_key(content_type):
  1541             raise ValueError("Unknown \"%s\" choice type for \"content\"!" % content_type)
  1539             raise ValueError("Unknown \"%s\" choice type for \"content\"!" % content_type)
  1542         choices[content_type]["elmt_type"] = FindTypeInfos(factory, choices[content_type]["elmt_type"])
  1540         choices[content_type]["elmt_type"] = FindTypeInfos(factory, choices[content_type]["elmt_type"])
  1543         new_content = choices[content_type]["elmt_type"]["initial"]()
  1541         new_content = choices[content_type]["elmt_type"]["initial"]()
       
  1542         DefaultElementClass.__setattr__(new_content, "tag", factory.etreeNamespaceFormat % content_type)
  1544         self.content = new_content
  1543         self.content = new_content
  1545         return new_content
  1544         return new_content
  1546     return setChoiceMethod
  1545     return setChoiceMethod
  1547 
  1546 
  1548 def generateAppendChoiceByTypeMethod(maxOccurs, factory, choice_types):
  1547 def generateAppendChoiceByTypeMethod(maxOccurs, factory, choice_types):
  1551         if not choices.has_key(content_type):
  1550         if not choices.has_key(content_type):
  1552             raise ValueError("Unknown \"%s\" choice type for \"content\"!" % content_type)
  1551             raise ValueError("Unknown \"%s\" choice type for \"content\"!" % content_type)
  1553         choices[content_type]["elmt_type"] = FindTypeInfos(factory, choices[content_type]["elmt_type"])
  1552         choices[content_type]["elmt_type"] = FindTypeInfos(factory, choices[content_type]["elmt_type"])
  1554         if maxOccurs == "unbounded" or len(self.content) < maxOccurs:
  1553         if maxOccurs == "unbounded" or len(self.content) < maxOccurs:
  1555             new_element = choices[content_type]["elmt_type"]["initial"]()
  1554             new_element = choices[content_type]["elmt_type"]["initial"]()
       
  1555             DefaultElementClass.__setattr__(new_element, "tag", factory.etreeNamespaceFormat % content_type)
  1556             self.appendcontent(new_element)
  1556             self.appendcontent(new_element)
  1557             return new_element
  1557             return new_element
  1558         else:
  1558         else:
  1559             raise ValueError("There can't be more than %d values in \"content\"!" % maxOccurs)
  1559             raise ValueError("There can't be more than %d values in \"content\"!" % maxOccurs)
  1560     return appendChoiceMethod
  1560     return appendChoiceMethod
  1565         if not choices.has_key(content_type):
  1565         if not choices.has_key(content_type):
  1566             raise ValueError("Unknown \"%s\" choice type for \"content\"!" % content_type)
  1566             raise ValueError("Unknown \"%s\" choice type for \"content\"!" % content_type)
  1567         choices[type]["elmt_type"] = FindTypeInfos(factory, choices[content_type]["elmt_type"])
  1567         choices[type]["elmt_type"] = FindTypeInfos(factory, choices[content_type]["elmt_type"])
  1568         if maxOccurs == "unbounded" or len(self.content) < maxOccurs:
  1568         if maxOccurs == "unbounded" or len(self.content) < maxOccurs:
  1569             new_element = choices[content_type]["elmt_type"]["initial"]()
  1569             new_element = choices[content_type]["elmt_type"]["initial"]()
       
  1570             DefaultElementClass.__setattr__(new_element, "tag", factory.etreeNamespaceFormat % content_type)
  1570             self.insertcontent(index, new_element)
  1571             self.insertcontent(index, new_element)
  1571             return new_element
  1572             return new_element
  1572         else:
  1573         else:
  1573             raise ValueError("There can't be more than %d values in \"content\"!" % maxOccurs)
  1574             raise ValueError("There can't be more than %d values in \"content\"!" % maxOccurs)
  1574     return insertChoiceMethod
  1575     return insertChoiceMethod
  1593 
  1594 
  1594 NAMESPACE_PATTERN = re.compile("xmlns(?:\:[^\=]*)?=\"[^\"]*\" ")
  1595 NAMESPACE_PATTERN = re.compile("xmlns(?:\:[^\=]*)?=\"[^\"]*\" ")
  1595 
  1596 
  1596 class DefaultElementClass(etree.ElementBase):
  1597 class DefaultElementClass(etree.ElementBase):
  1597     
  1598     
  1598     def init(self):
  1599     def _init_(self):
  1599         pass
  1600         pass
  1600     
  1601     
  1601     def getLocalTag(self):
  1602     def getLocalTag(self):
  1602         return etree.QName(self.tag).localname
  1603         return etree.QName(self.tag).localname
  1603         
  1604         
  1655     def CreateRoot(self):
  1656     def CreateRoot(self):
  1656         if self.BaseClass is not None:
  1657         if self.BaseClass is not None:
  1657             root = self.makeelement(
  1658             root = self.makeelement(
  1658                 self.DefaultNamespaceFormat % self.BaseClass[0],
  1659                 self.DefaultNamespaceFormat % self.BaseClass[0],
  1659                 nsmap=self.RootNSMAP)
  1660                 nsmap=self.RootNSMAP)
  1660             root.init()
  1661             root._init_()
  1661             return root
  1662             return root
  1662         return None
  1663         return None
  1663     
  1664     
  1664     def GetElementClass(self, element_tag, parent_tag=None):
  1665     def GetElementClass(self, element_tag, parent_tag=None):
  1665         return self.ClassLookup.GetElementClass(
  1666         return self.ClassLookup.GetElementClass(
  1669             None)
  1670             None)
  1670     
  1671     
  1671     def CreateElement(self, element_tag, parent_tag=None):
  1672     def CreateElement(self, element_tag, parent_tag=None):
  1672         new_element = self.GetElementClass(element_tag, parent_tag)()
  1673         new_element = self.GetElementClass(element_tag, parent_tag)()
  1673         DefaultElementClass.__setattr__(new_element, "tag", self.DefaultNamespaceFormat % element_tag)
  1674         DefaultElementClass.__setattr__(new_element, "tag", self.DefaultNamespaceFormat % element_tag)
  1674         new_element.init()
  1675         new_element._init_()
  1675         return new_element
  1676         return new_element
  1676     
  1677     
  1677 def GenerateParser(factory, xsdstring):
  1678 def GenerateParser(factory, xsdstring):
  1678     ComputedClasses = factory.CreateClasses()
  1679     ComputedClasses = factory.CreateClasses()
  1679     if factory.FileName is not None and len(ComputedClasses) == 1:
  1680     if factory.FileName is not None and len(ComputedClasses) == 1:
  1680         ComputedClasses = ComputedClasses[factory.FileName]
  1681         ComputedClasses = ComputedClasses[factory.FileName]
  1681         BaseClass = [(name, XSDclass) for name, XSDclass in ComputedClasses.items() if XSDclass.IsBaseClass]
  1682     BaseClass = [(name, XSDclass) for name, XSDclass in ComputedClasses.items() if XSDclass.IsBaseClass]
  1682     else:
       
  1683         BaseClass = []
       
  1684     UpdateXMLClassGlobals(ComputedClasses)
  1683     UpdateXMLClassGlobals(ComputedClasses)
  1685     
  1684     
  1686     parser = XMLClassParser(
  1685     parser = XMLClassParser(
  1687         factory.NSMAP,
  1686         factory.NSMAP,
  1688         factory.etreeNamespaceFormat,
  1687         factory.etreeNamespaceFormat,