153 return value.replace("\t", " ").replace("\r", " ").replace("\n", " ") |
153 return value.replace("\t", " ").replace("\r", " ").replace("\n", " ") |
154 |
154 |
155 |
155 |
156 def GetToken(attr, extract=True): |
156 def GetToken(attr, extract=True): |
157 """ |
157 """ |
158 Function that tokenizes a string according to XML 1.0. Remove any leading |
158 Function that tokenizes a string according to XML 1.0. Remove any leading |
159 and trailing white space and replace internal sequence of two or more |
159 and trailing white space and replace internal sequence of two or more |
160 spaces by only one white space |
160 spaces by only one white space |
161 @param attr: tree node containing data to extract or data to tokenize |
161 @param attr: tree node containing data to extract or data to tokenize |
162 @param extract: attr is a tree node or not |
162 @param extract: attr is a tree node or not |
163 @return: data tokenized as string |
163 @return: data tokenized as string |
164 """ |
164 """ |
165 return " ".join([part for part in |
165 return " ".join([part for part in |
166 GetNormalizedString(attr, extract).split(" ") |
166 GetNormalizedString(attr, extract).split(" ") |
167 if part]) |
167 if part]) |
168 |
168 |
169 |
169 |
170 def GetHexInteger(attr, extract=True): |
170 def GetHexInteger(attr, extract=True): |
533 (value, type)) |
533 (value, type)) |
534 return values |
534 return values |
535 return GetModelNameList |
535 return GetModelNameList |
536 |
536 |
537 def GenerateAnyInfos(infos): |
537 def GenerateAnyInfos(infos): |
538 |
538 |
539 def GetTextElement(tree): |
539 def GetTextElement(tree): |
540 if infos["namespace"][0] == "##any": |
540 if infos["namespace"][0] == "##any": |
541 return tree.xpath("p")[0] |
541 return tree.xpath("p")[0] |
542 return tree.xpath("ns:p", namespaces={"ns": infos["namespace"][0]})[0] |
542 return tree.xpath("ns:p", namespaces={"ns": infos["namespace"][0]})[0] |
543 |
543 |
544 def ExtractAny(tree): |
544 def ExtractAny(tree): |
545 return GetTextElement(tree).text |
545 return GetTextElement(tree).text |
546 |
546 |
547 def GenerateAny(tree, value): |
547 def GenerateAny(tree, value): |
548 GetTextElement(tree).text = etree.CDATA(value) |
548 GetTextElement(tree).text = etree.CDATA(value) |
549 |
549 |
550 def InitialAny(): |
550 def InitialAny(): |
551 if infos["namespace"][0] == "##any": |
551 if infos["namespace"][0] == "##any": |
552 element_name = "p" |
552 element_name = "p" |
553 else: |
553 else: |
554 element_name = "{%s}p" % infos["namespace"][0] |
554 element_name = "{%s}p" % infos["namespace"][0] |
555 p = etree.Element(element_name) |
555 p = etree.Element(element_name) |
556 p.text = etree.CDATA("") |
556 p.text = etree.CDATA("") |
557 return p |
557 return p |
558 |
558 |
559 return { |
559 return { |
560 "type": COMPLEXTYPE, |
560 "type": COMPLEXTYPE, |
561 "extract": ExtractAny, |
561 "extract": ExtractAny, |
562 "generate": GenerateAny, |
562 "generate": GenerateAny, |
563 "initial": InitialAny, |
563 "initial": InitialAny, |
564 "check": lambda x: isinstance(x, (StringType, UnicodeType, etree.ElementBase)) |
564 "check": lambda x: isinstance(x, (StringType, UnicodeType, etree.ElementBase)) |
565 } |
565 } |
572 raise ValueError("\"%s\" musn't have children!" % infos["name"]) |
572 raise ValueError("\"%s\" musn't have children!" % infos["name"]) |
573 if infos["minOccurs"] == 0: |
573 if infos["minOccurs"] == 0: |
574 return True |
574 return True |
575 else: |
575 else: |
576 return None |
576 return None |
577 |
577 |
578 def GenerateTag(value, name=None, indent=0): |
578 def GenerateTag(value, name=None, indent=0): |
579 if name is not None and not (infos["minOccurs"] == 0 and value is None): |
579 if name is not None and not (infos["minOccurs"] == 0 and value is None): |
580 ind1, ind2 = getIndent(indent, name) |
580 ind1, ind2 = getIndent(indent, name) |
581 return ind1 + "<%s/>\n" % name |
581 return ind1 + "<%s/>\n" % name |
582 else: |
582 else: |
583 return "" |
583 return "" |
584 |
584 |
585 return { |
585 return { |
586 "type": TAG, |
586 "type": TAG, |
587 "extract": ExtractTag, |
587 "extract": ExtractTag, |
588 "generate": GenerateTag, |
588 "generate": GenerateTag, |
589 "initial": lambda: None, |
589 "initial": lambda: None, |
590 "check": lambda x: x == None or infos["minOccurs"] == 0 and value == True |
590 "check": lambda x: x == None or infos["minOccurs"] == 0 and value == True |
591 } |
591 } |
593 def FindTypeInfos(factory, infos): |
593 def FindTypeInfos(factory, infos): |
594 if isinstance(infos, (UnicodeType, StringType)): |
594 if isinstance(infos, (UnicodeType, StringType)): |
595 namespace, name = DecomposeQualifiedName(infos) |
595 namespace, name = DecomposeQualifiedName(infos) |
596 return factory.GetQualifiedNameInfos(name, namespace) |
596 return factory.GetQualifiedNameInfos(name, namespace) |
597 return infos |
597 return infos |
598 |
598 |
599 def GetElementInitialValue(factory, infos): |
599 def GetElementInitialValue(factory, infos): |
600 infos["elmt_type"] = FindTypeInfos(factory, infos["elmt_type"]) |
600 infos["elmt_type"] = FindTypeInfos(factory, infos["elmt_type"]) |
601 if infos["minOccurs"] == 1: |
601 if infos["minOccurs"] == 1: |
602 element_name = factory.etreeNamespaceFormat % infos["name"] |
602 element_name = factory.etreeNamespaceFormat % infos["name"] |
603 if infos["elmt_type"]["type"] == SIMPLETYPE: |
603 if infos["elmt_type"]["type"] == SIMPLETYPE: |
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 prefix = ("%s:" % factory.TargetNamespace |
667 prefix = ("%s:" % factory.TargetNamespace |
668 if factory.TargetNamespace is not None else "") |
668 if factory.TargetNamespace is not None else "") |
669 choices_xpath = "|".join(map(lambda x: prefix + x, choices_dict.keys())) |
669 choices_xpath = "|".join(map(lambda x: prefix + x, choices_dict.keys())) |
670 |
670 |
671 def GetContentInitial(): |
671 def GetContentInitial(): |
672 content_name, infos = choices[0] |
672 content_name, infos = choices[0] |
673 if content_name == "sequence": |
673 if content_name == "sequence": |
674 content_value = [] |
674 content_value = [] |
675 for i in xrange(infos["minOccurs"]): |
675 for i in xrange(infos["minOccurs"]): |
676 for element_infos in infos["elements"]: |
676 for element_infos in infos["elements"]: |
677 content_value.extend(GetElementInitialValue(factory, element_infos)) |
677 content_value.extend(GetElementInitialValue(factory, element_infos)) |
678 else: |
678 else: |
679 content_value = GetElementInitialValue(factory, infos) |
679 content_value = GetElementInitialValue(factory, infos) |
680 return content_value |
680 return content_value |
681 |
681 |
682 return { |
682 return { |
683 "type": COMPLEXTYPE, |
683 "type": COMPLEXTYPE, |
684 "choices_xpath": etree.XPath(choices_xpath, namespaces=factory.NSMAP), |
684 "choices_xpath": etree.XPath(choices_xpath, namespaces=factory.NSMAP), |
685 "initial": GetContentInitial, |
685 "initial": GetContentInitial, |
686 } |
686 } |
691 |
691 |
692 |
692 |
693 def DecomposeQualifiedName(name): |
693 def DecomposeQualifiedName(name): |
694 result = QName_model.match(name) |
694 result = QName_model.match(name) |
695 if not result: |
695 if not result: |
696 raise ValueError("\"%s\" isn't a valid QName value!" % name) |
696 raise ValueError("\"%s\" isn't a valid QName value!" % name) |
697 parts = result.groups()[0].split(':') |
697 parts = result.groups()[0].split(':') |
698 if len(parts) == 1: |
698 if len(parts) == 1: |
699 return None, parts[0] |
699 return None, parts[0] |
700 return parts |
700 return parts |
701 |
701 |
702 def GenerateElement(element_name, attributes, elements_model, |
702 def GenerateElement(element_name, attributes, elements_model, |
703 accept_text=False): |
703 accept_text=False): |
704 def ExtractElement(factory, node): |
704 def ExtractElement(factory, node): |
705 attrs = factory.ExtractNodeAttrs(element_name, node, attributes) |
705 attrs = factory.ExtractNodeAttrs(element_name, node, attributes) |
706 children_structure = "" |
706 children_structure = "" |
707 children_infos = [] |
707 children_infos = [] |
744 if filepath is not None: |
744 if filepath is not None: |
745 self.BaseFolder, self.FileName = os.path.split(filepath) |
745 self.BaseFolder, self.FileName = os.path.split(filepath) |
746 else: |
746 else: |
747 self.BaseFolder = self.FileName = None |
747 self.BaseFolder = self.FileName = None |
748 self.Debug = debug |
748 self.Debug = debug |
749 |
749 |
750 # Dictionary for stocking Classes and Types definitions created from |
750 # Dictionary for stocking Classes and Types definitions created from |
751 # the XML tree |
751 # the XML tree |
752 self.XMLClassDefinitions = {} |
752 self.XMLClassDefinitions = {} |
753 |
753 |
754 self.DefinedNamespaces = {} |
754 self.DefinedNamespaces = {} |
755 self.NSMAP = {} |
755 self.NSMAP = {} |
756 self.Namespaces = {} |
756 self.Namespaces = {} |
757 self.SchemaNamespace = None |
757 self.SchemaNamespace = None |
758 self.TargetNamespace = None |
758 self.TargetNamespace = None |
759 self.etreeNamespaceFormat = "%s" |
759 self.etreeNamespaceFormat = "%s" |
760 |
760 |
761 self.CurrentCompilations = [] |
761 self.CurrentCompilations = [] |
762 |
762 |
763 # Dictionaries for stocking Classes and Types generated |
763 # Dictionaries for stocking Classes and Types generated |
764 self.ComputeAfter = [] |
764 self.ComputeAfter = [] |
765 if self.FileName is not None: |
765 if self.FileName is not None: |
766 self.ComputedClasses = {self.FileName: {}} |
766 self.ComputedClasses = {self.FileName: {}} |
767 else: |
767 else: |
918 else: |
918 else: |
919 raise ValueError("\"%s\" class already defined. Choose another name!" % typename) |
919 raise ValueError("\"%s\" class already defined. Choose another name!" % typename) |
920 |
920 |
921 def ParseSchema(self): |
921 def ParseSchema(self): |
922 pass |
922 pass |
923 |
923 |
924 def AddEquivalentClass(self, name, base): |
924 def AddEquivalentClass(self, name, base): |
925 if name != base: |
925 if name != base: |
926 equivalences = self.EquivalentClassesParent.setdefault(self.etreeNamespaceFormat % base, {}) |
926 equivalences = self.EquivalentClassesParent.setdefault(self.etreeNamespaceFormat % base, {}) |
927 equivalences[self.etreeNamespaceFormat % name] = True |
927 equivalences[self.etreeNamespaceFormat % name] = True |
928 |
928 |
929 def AddDistinctionBetweenParentsInLookupClass( |
929 def AddDistinctionBetweenParentsInLookupClass( |
930 self, lookup_classes, parent, typeinfos): |
930 self, lookup_classes, parent, typeinfos): |
931 parent = (self.etreeNamespaceFormat % parent |
931 parent = (self.etreeNamespaceFormat % parent |
932 if parent is not None else None) |
932 if parent is not None else None) |
933 parent_class = lookup_classes.get(parent) |
933 parent_class = lookup_classes.get(parent) |
934 if parent_class is not None: |
934 if parent_class is not None: |
935 if isinstance(parent_class, ListType): |
935 if isinstance(parent_class, ListType): |
936 if typeinfos not in parent_class: |
936 if typeinfos not in parent_class: |
937 lookup_classes[parent].append(typeinfos) |
937 lookup_classes[parent].append(typeinfos) |
938 elif parent_class != typeinfos: |
938 elif parent_class != typeinfos: |
939 lookup_classes[parent] = [typeinfos, parent_class] |
939 lookup_classes[parent] = [typeinfos, parent_class] |
940 else: |
940 else: |
941 lookup_classes[parent] = typeinfos |
941 lookup_classes[parent] = typeinfos |
942 |
942 |
943 def AddToLookupClass(self, name, parent, typeinfos): |
943 def AddToLookupClass(self, name, parent, typeinfos): |
944 lookup_name = self.etreeNamespaceFormat % name |
944 lookup_name = self.etreeNamespaceFormat % name |
945 if isinstance(typeinfos, (StringType, UnicodeType)): |
945 if isinstance(typeinfos, (StringType, UnicodeType)): |
946 self.AddEquivalentClass(name, typeinfos) |
946 self.AddEquivalentClass(name, typeinfos) |
947 typeinfos = self.etreeNamespaceFormat % typeinfos |
947 typeinfos = self.etreeNamespaceFormat % typeinfos |
956 self.etreeNamespaceFormat % lookup_classes[1] |
956 self.etreeNamespaceFormat % lookup_classes[1] |
957 if lookup_classes[1] is not None else None: lookup_classes[0]} |
957 if lookup_classes[1] is not None else None: lookup_classes[0]} |
958 self.AddDistinctionBetweenParentsInLookupClass( |
958 self.AddDistinctionBetweenParentsInLookupClass( |
959 lookup_classes, parent, typeinfos) |
959 lookup_classes, parent, typeinfos) |
960 self.ComputedClassesLookUp[lookup_name] = lookup_classes |
960 self.ComputedClassesLookUp[lookup_name] = lookup_classes |
961 |
961 |
962 def ExtractTypeInfos(self, name, parent, typeinfos): |
962 def ExtractTypeInfos(self, name, parent, typeinfos): |
963 if isinstance(typeinfos, (StringType, UnicodeType)): |
963 if isinstance(typeinfos, (StringType, UnicodeType)): |
964 namespace, type_name = DecomposeQualifiedName(typeinfos) |
964 namespace, type_name = DecomposeQualifiedName(typeinfos) |
965 infos = self.GetQualifiedNameInfos(type_name, namespace) |
965 infos = self.GetQualifiedNameInfos(type_name, namespace) |
966 if name != "base": |
966 if name != "base": |
984 return infos |
984 return infos |
985 elif typeinfos["type"] == COMPLEXTYPE: |
985 elif typeinfos["type"] == COMPLEXTYPE: |
986 return self.CreateClass(name, parent, typeinfos) |
986 return self.CreateClass(name, parent, typeinfos) |
987 elif typeinfos["type"] == SIMPLETYPE: |
987 elif typeinfos["type"] == SIMPLETYPE: |
988 return typeinfos |
988 return typeinfos |
989 |
989 |
990 def GetEquivalentParents(self, parent): |
990 def GetEquivalentParents(self, parent): |
991 return reduce(lambda x, y: x + y, |
991 return reduce(lambda x, y: x + y, |
992 [[p] + self.GetEquivalentParents(p) |
992 [[p] + self.GetEquivalentParents(p) |
993 for p in self.EquivalentClassesParent.get(parent, {}).keys()], []) |
993 for p in self.EquivalentClassesParent.get(parent, {}).keys()], []) |
994 |
994 |
995 """ |
995 """ |
996 Methods that generates the classes |
996 Methods that generates the classes |
997 """ |
997 """ |
998 def CreateClasses(self): |
998 def CreateClasses(self): |
999 self.ParseSchema() |
999 self.ParseSchema() |
1026 while len(self.ComputeAfter) > 0: |
1026 while len(self.ComputeAfter) > 0: |
1027 result = self.CreateClass(*self.ComputeAfter.pop(0)) |
1027 result = self.CreateClass(*self.ComputeAfter.pop(0)) |
1028 if result is not None and \ |
1028 if result is not None and \ |
1029 not isinstance(result, (UnicodeType, StringType)): |
1029 not isinstance(result, (UnicodeType, StringType)): |
1030 self.Namespaces[self.TargetNamespace][result["name"]] = result |
1030 self.Namespaces[self.TargetNamespace][result["name"]] = result |
1031 |
1031 |
1032 for name, parents in self.ComputedClassesLookUp.iteritems(): |
1032 for name, parents in self.ComputedClassesLookUp.iteritems(): |
1033 if isinstance(parents, DictType): |
1033 if isinstance(parents, DictType): |
1034 computed_classes = parents.items() |
1034 computed_classes = parents.items() |
1035 elif parents[1] is not None: |
1035 elif parents[1] is not None: |
1036 computed_classes = [(self.etreeNamespaceFormat % parents[1], parents[0])] |
1036 computed_classes = [(self.etreeNamespaceFormat % parents[1], parents[0])] |
1040 for equivalent_parent in self.GetEquivalentParents(parent): |
1040 for equivalent_parent in self.GetEquivalentParents(parent): |
1041 if not isinstance(parents, DictType): |
1041 if not isinstance(parents, DictType): |
1042 parents = dict(computed_classes) |
1042 parents = dict(computed_classes) |
1043 self.ComputedClassesLookUp[name] = parents |
1043 self.ComputedClassesLookUp[name] = parents |
1044 parents[equivalent_parent] = computed_class |
1044 parents[equivalent_parent] = computed_class |
1045 |
1045 |
1046 return self.ComputedClasses |
1046 return self.ComputedClasses |
1047 |
1047 |
1048 def CreateClass(self, name, parent, classinfos, baseclass = False): |
1048 def CreateClass(self, name, parent, classinfos, baseclass = False): |
1049 if parent is not None: |
1049 if parent is not None: |
1050 classname = "%s_%s" % (parent, name) |
1050 classname = "%s_%s" % (parent, name) |
1051 else: |
1051 else: |
1052 classname = name |
1052 classname = name |
1053 |
1053 |
1054 # Checks that classe haven't been generated yet |
1054 # Checks that classe haven't been generated yet |
1055 if self.AlreadyComputed.get(classname, False): |
1055 if self.AlreadyComputed.get(classname, False): |
1056 return self.ComputedClassesInfos.get(classname, None) |
1056 return self.ComputedClassesInfos.get(classname, None) |
1057 |
1057 |
1058 # If base classes haven't been generated |
1058 # If base classes haven't been generated |
1059 bases = [] |
1059 bases = [] |
1060 base_infos = classinfos.get("base", None) |
1060 base_infos = classinfos.get("base", None) |
1061 if base_infos is not None: |
1061 if base_infos is not None: |
1062 namespace, base_name = DecomposeQualifiedName(base_infos) |
1062 namespace, base_name = DecomposeQualifiedName(base_infos) |
1086 raise ValueError("No class found for base type") |
1086 raise ValueError("No class found for base type") |
1087 bases.append(classinfos["base"]) |
1087 bases.append(classinfos["base"]) |
1088 bases.append(DefaultElementClass) |
1088 bases.append(DefaultElementClass) |
1089 bases = tuple(bases) |
1089 bases = tuple(bases) |
1090 classmembers = {"__doc__": classinfos.get("doc", ""), "IsBaseClass": baseclass} |
1090 classmembers = {"__doc__": classinfos.get("doc", ""), "IsBaseClass": baseclass} |
1091 |
1091 |
1092 self.AlreadyComputed[classname] = True |
1092 self.AlreadyComputed[classname] = True |
1093 |
1093 |
1094 for attribute in classinfos["attributes"]: |
1094 for attribute in classinfos["attributes"]: |
1095 infos = self.ExtractTypeInfos(attribute["name"], name, attribute["attr_type"]) |
1095 infos = self.ExtractTypeInfos(attribute["name"], name, attribute["attr_type"]) |
1096 if infos is not None: |
1096 if infos is not None: |
1097 if infos["type"] != SIMPLETYPE: |
1097 if infos["type"] != SIMPLETYPE: |
1098 raise ValueError("\"%s\" type is not a simple type!" % attribute["attr_type"]) |
1098 raise ValueError("\"%s\" type is not a simple type!" % attribute["attr_type"]) |
1099 attrname = attribute["name"] |
1099 attrname = attribute["name"] |
1100 if attribute["use"] == "optional": |
1100 if attribute["use"] == "optional": |
1101 classmembers["add%s"%attrname] = generateAddMethod(attrname, self, attribute) |
1101 classmembers["add%s"%attrname] = generateAddMethod(attrname, self, attribute) |
1103 classmembers["set%s"%attrname] = generateSetMethod(attrname) |
1103 classmembers["set%s"%attrname] = generateSetMethod(attrname) |
1104 classmembers["get%s"%attrname] = generateGetMethod(attrname) |
1104 classmembers["get%s"%attrname] = generateGetMethod(attrname) |
1105 else: |
1105 else: |
1106 raise ValueError("\"%s\" type unrecognized!" % attribute["attr_type"]) |
1106 raise ValueError("\"%s\" type unrecognized!" % attribute["attr_type"]) |
1107 attribute["attr_type"] = infos |
1107 attribute["attr_type"] = infos |
1108 |
1108 |
1109 for element in classinfos["elements"]: |
1109 for element in classinfos["elements"]: |
1110 if element["type"] == CHOICE: |
1110 if element["type"] == CHOICE: |
1111 elmtname = element["name"] |
1111 elmtname = element["name"] |
1112 choices = ComputeContentChoices(self, name, element) |
1112 choices = ComputeContentChoices(self, name, element) |
1113 classmembers["get%schoices"%elmtname] = generateGetChoicesMethod(element["choices"]) |
1113 classmembers["get%schoices"%elmtname] = generateGetChoicesMethod(element["choices"]) |
1139 if element["minOccurs"] == 0: |
1139 if element["minOccurs"] == 0: |
1140 classmembers["add%s" % elmtname] = generateAddMethod(elmtname, self, element) |
1140 classmembers["add%s" % elmtname] = generateAddMethod(elmtname, self, element) |
1141 classmembers["delete%s" % elmtname] = generateDeleteMethod(elmtname) |
1141 classmembers["delete%s" % elmtname] = generateDeleteMethod(elmtname) |
1142 classmembers["set%s" % elmtname] = generateSetMethod(elmtname) |
1142 classmembers["set%s" % elmtname] = generateSetMethod(elmtname) |
1143 classmembers["get%s" % elmtname] = generateGetMethod(elmtname) |
1143 classmembers["get%s" % elmtname] = generateGetMethod(elmtname) |
1144 |
1144 |
1145 classmembers["_init_"] = generateInitMethod(self, classinfos) |
1145 classmembers["_init_"] = generateInitMethod(self, classinfos) |
1146 classmembers["StructurePattern"] = GetStructurePattern(classinfos) |
1146 classmembers["StructurePattern"] = GetStructurePattern(classinfos) |
1147 classmembers["getElementAttributes"] = generateGetElementAttributes(self, classinfos) |
1147 classmembers["getElementAttributes"] = generateGetElementAttributes(self, classinfos) |
1148 classmembers["getElementInfos"] = generateGetElementInfos(self, classinfos) |
1148 classmembers["getElementInfos"] = generateGetElementInfos(self, classinfos) |
1149 classmembers["setElementValue"] = generateSetElementValue(self, classinfos) |
1149 classmembers["setElementValue"] = generateSetElementValue(self, classinfos) |
1150 |
1150 |
1151 class_definition = classobj(str(name), bases, classmembers) |
1151 class_definition = classobj(str(name), bases, classmembers) |
1152 setattr(class_definition, "__getattr__", generateGetattrMethod(self, class_definition, classinfos)) |
1152 setattr(class_definition, "__getattr__", generateGetattrMethod(self, class_definition, classinfos)) |
1153 setattr(class_definition, "__setattr__", generateSetattrMethod(self, class_definition, classinfos)) |
1153 setattr(class_definition, "__setattr__", generateSetattrMethod(self, class_definition, classinfos)) |
1154 class_infos = {"type": COMPILEDCOMPLEXTYPE, |
1154 class_infos = {"type": COMPILEDCOMPLEXTYPE, |
1155 "name": classname, |
1155 "name": classname, |
1156 "initial": generateClassCreateFunction(class_definition), |
1156 "initial": generateClassCreateFunction(class_definition), |
1157 } |
1157 } |
1158 |
1158 |
1159 if self.FileName is not None: |
1159 if self.FileName is not None: |
1160 self.ComputedClasses[self.FileName][classname] = class_definition |
1160 self.ComputedClasses[self.FileName][classname] = class_definition |
1161 else: |
1161 else: |
1162 self.ComputedClasses[classname] = class_definition |
1162 self.ComputedClasses[classname] = class_definition |
1163 self.ComputedClassesInfos[classname] = class_infos |
1163 self.ComputedClassesInfos[classname] = class_infos |
1164 |
1164 |
1165 self.AddToLookupClass(name, parent, class_definition) |
1165 self.AddToLookupClass(name, parent, class_definition) |
1166 self.AddToLookupClass(classname, None, class_definition) |
1166 self.AddToLookupClass(classname, None, class_definition) |
1167 |
1167 |
1168 return class_infos |
1168 return class_infos |
1169 |
1169 |
1170 """ |
1170 """ |
1171 Methods that print the classes generated |
1171 Methods that print the classes generated |
1172 """ |
1172 """ |
1181 for classname, xmlclass in class_items: |
1181 for classname, xmlclass in class_items: |
1182 print "%s: %s" % (classname, str(xmlclass)) |
1182 print "%s: %s" % (classname, str(xmlclass)) |
1183 else: |
1183 else: |
1184 for classname, xmlclass in items: |
1184 for classname, xmlclass in items: |
1185 print "%s: %s" % (classname, str(xmlclass)) |
1185 print "%s: %s" % (classname, str(xmlclass)) |
1186 |
1186 |
1187 def PrintClassNames(self): |
1187 def PrintClassNames(self): |
1188 classnames = self.XMLClassDefinitions.keys() |
1188 classnames = self.XMLClassDefinitions.keys() |
1189 classnames.sort() |
1189 classnames.sort() |
1190 for classname in classnames: |
1190 for classname in classnames: |
1191 print classname |
1191 print classname |
1192 |
1192 |
1193 """ |
1193 """ |
1194 Method that generate the method for generating the xml tree structure model by |
1194 Method that generate the method for generating the xml tree structure model by |
1195 following the attributes list defined |
1195 following the attributes list defined |
1196 """ |
1196 """ |
1197 def ComputeMultiplicity(name, infos): |
1197 def ComputeMultiplicity(name, infos): |
1198 if infos["minOccurs"] == 0: |
1198 if infos["minOccurs"] == 0: |
1199 if infos["maxOccurs"] == "unbounded": |
1199 if infos["maxOccurs"] == "unbounded": |
1211 return "(?:%s){1,%d}" % (name, infos["maxOccurs"]) |
1211 return "(?:%s){1,%d}" % (name, infos["maxOccurs"]) |
1212 else: |
1212 else: |
1213 if infos["maxOccurs"] == "unbounded": |
1213 if infos["maxOccurs"] == "unbounded": |
1214 return "(?:%s){%d,}" % (name, infos["minOccurs"], name) |
1214 return "(?:%s){%d,}" % (name, infos["minOccurs"], name) |
1215 else: |
1215 else: |
1216 return "(?:%s){%d,%d}" % (name, infos["minOccurs"], |
1216 return "(?:%s){%d,%d}" % (name, infos["minOccurs"], |
1217 infos["maxOccurs"]) |
1217 infos["maxOccurs"]) |
1218 |
1218 |
1219 def GetStructurePattern(classinfos): |
1219 def GetStructurePattern(classinfos): |
1220 base_structure_pattern = ( |
1220 base_structure_pattern = ( |
1221 classinfos["base"].StructurePattern.pattern[:-1] |
1221 classinfos["base"].StructurePattern.pattern[:-1] |
1254 |
1254 |
1255 def generateGetattrMethod(factory, class_definition, classinfos): |
1255 def generateGetattrMethod(factory, class_definition, classinfos): |
1256 attributes = dict([(attr["name"], attr) for attr in classinfos["attributes"] if attr["use"] != "prohibited"]) |
1256 attributes = dict([(attr["name"], attr) for attr in classinfos["attributes"] if attr["use"] != "prohibited"]) |
1257 optional_attributes = dict([(attr["name"], True) for attr in classinfos["attributes"] if attr["use"] == "optional"]) |
1257 optional_attributes = dict([(attr["name"], True) for attr in classinfos["attributes"] if attr["use"] == "optional"]) |
1258 elements = dict([(element["name"], element) for element in classinfos["elements"]]) |
1258 elements = dict([(element["name"], element) for element in classinfos["elements"]]) |
1259 |
1259 |
1260 def getattrMethod(self, name): |
1260 def getattrMethod(self, name): |
1261 if attributes.has_key(name): |
1261 if attributes.has_key(name): |
1262 attribute_infos = attributes[name] |
1262 attribute_infos = attributes[name] |
1263 attribute_infos["attr_type"] = FindTypeInfos(factory, attribute_infos["attr_type"]) |
1263 attribute_infos["attr_type"] = FindTypeInfos(factory, attribute_infos["attr_type"]) |
1264 value = self.get(name) |
1264 value = self.get(name) |
1267 elif attribute_infos.has_key("fixed"): |
1267 elif attribute_infos.has_key("fixed"): |
1268 return attribute_infos["attr_type"]["extract"](attribute_infos["fixed"], extract=False) |
1268 return attribute_infos["attr_type"]["extract"](attribute_infos["fixed"], extract=False) |
1269 elif attribute_infos.has_key("default"): |
1269 elif attribute_infos.has_key("default"): |
1270 return attribute_infos["attr_type"]["extract"](attribute_infos["default"], extract=False) |
1270 return attribute_infos["attr_type"]["extract"](attribute_infos["default"], extract=False) |
1271 return None |
1271 return None |
1272 |
1272 |
1273 elif elements.has_key(name): |
1273 elif elements.has_key(name): |
1274 element_infos = elements[name] |
1274 element_infos = elements[name] |
1275 element_infos["elmt_type"] = FindTypeInfos(factory, element_infos["elmt_type"]) |
1275 element_infos["elmt_type"] = FindTypeInfos(factory, element_infos["elmt_type"]) |
1276 if element_infos["type"] == CHOICE: |
1276 if element_infos["type"] == CHOICE: |
1277 content = element_infos["elmt_type"]["choices_xpath"](self) |
1277 content = element_infos["elmt_type"]["choices_xpath"](self) |
1278 if element_infos["maxOccurs"] == "unbounded" or element_infos["maxOccurs"] > 1: |
1278 if element_infos["maxOccurs"] == "unbounded" or element_infos["maxOccurs"] > 1: |
1279 return content |
1279 return content |
1280 elif len(content) > 0: |
1280 elif len(content) > 0: |
1281 return content[0] |
1281 return content[0] |
1282 return None |
1282 return None |
1283 elif element_infos["type"] == ANY: |
1283 elif element_infos["type"] == ANY: |
1284 return element_infos["elmt_type"]["extract"](self) |
1284 return element_infos["elmt_type"]["extract"](self) |
1285 elif name == "content" and element_infos["elmt_type"]["type"] == SIMPLETYPE: |
1285 elif name == "content" and element_infos["elmt_type"]["type"] == SIMPLETYPE: |
1286 return element_infos["elmt_type"]["extract"](self.text, extract=False) |
1286 return element_infos["elmt_type"]["extract"](self.text, extract=False) |
1287 else: |
1287 else: |
1288 element_name = factory.etreeNamespaceFormat % name |
1288 element_name = factory.etreeNamespaceFormat % name |
1289 if element_infos["maxOccurs"] == "unbounded" or element_infos["maxOccurs"] > 1: |
1289 if element_infos["maxOccurs"] == "unbounded" or element_infos["maxOccurs"] > 1: |
1290 values = self.findall(element_name) |
1290 values = self.findall(element_name) |
1291 if element_infos["elmt_type"]["type"] == SIMPLETYPE: |
1291 if element_infos["elmt_type"]["type"] == SIMPLETYPE: |
1292 return map(lambda value: |
1292 return map(lambda value: |
1293 element_infos["elmt_type"]["extract"](value.text, extract=False), |
1293 element_infos["elmt_type"]["extract"](value.text, extract=False), |
1294 values) |
1294 values) |
1295 return values |
1295 return values |
1296 else: |
1296 else: |
1297 value = self.find(element_name) |
1297 value = self.find(element_name) |
1298 if element_infos["elmt_type"]["type"] == SIMPLETYPE: |
1298 if element_infos["elmt_type"]["type"] == SIMPLETYPE: |
1299 return element_infos["elmt_type"]["extract"](value.text, extract=False) |
1299 return element_infos["elmt_type"]["extract"](value.text, extract=False) |
1300 return value |
1300 return value |
1301 |
1301 |
1302 elif classinfos.has_key("base"): |
1302 elif classinfos.has_key("base"): |
1303 return classinfos["base"].__getattr__(self, name) |
1303 return classinfos["base"].__getattr__(self, name) |
1304 |
1304 |
1305 return DefaultElementClass.__getattribute__(self, name) |
1305 return DefaultElementClass.__getattribute__(self, name) |
1306 |
1306 |
1307 return getattrMethod |
1307 return getattrMethod |
1308 |
1308 |
1309 def generateSetattrMethod(factory, class_definition, classinfos): |
1309 def generateSetattrMethod(factory, class_definition, classinfos): |
1310 attributes = dict([(attr["name"], attr) for attr in classinfos["attributes"] if attr["use"] != "prohibited"]) |
1310 attributes = dict([(attr["name"], attr) for attr in classinfos["attributes"] if attr["use"] != "prohibited"]) |
1311 optional_attributes = dict([(attr["name"], True) for attr in classinfos["attributes"] if attr["use"] == "optional"]) |
1311 optional_attributes = dict([(attr["name"], True) for attr in classinfos["attributes"] if attr["use"] == "optional"]) |
1312 elements = OrderedDict([(element["name"], element) for element in classinfos["elements"]]) |
1312 elements = OrderedDict([(element["name"], element) for element in classinfos["elements"]]) |
1313 |
1313 |
1314 def setattrMethod(self, name, value): |
1314 def setattrMethod(self, name, value): |
1315 if attributes.has_key(name): |
1315 if attributes.has_key(name): |
1316 attribute_infos = attributes[name] |
1316 attribute_infos = attributes[name] |
1317 attribute_infos["attr_type"] = FindTypeInfos(factory, attribute_infos["attr_type"]) |
1317 attribute_infos["attr_type"] = FindTypeInfos(factory, attribute_infos["attr_type"]) |
1318 if optional_attributes.get(name, False): |
1318 if optional_attributes.get(name, False): |
1321 self.attrib.pop(name, None) |
1321 self.attrib.pop(name, None) |
1322 return |
1322 return |
1323 elif attribute_infos.has_key("fixed"): |
1323 elif attribute_infos.has_key("fixed"): |
1324 return |
1324 return |
1325 return self.set(name, attribute_infos["attr_type"]["generate"](value)) |
1325 return self.set(name, attribute_infos["attr_type"]["generate"](value)) |
1326 |
1326 |
1327 elif elements.has_key(name): |
1327 elif elements.has_key(name): |
1328 element_infos = elements[name] |
1328 element_infos = elements[name] |
1329 element_infos["elmt_type"] = FindTypeInfos(factory, element_infos["elmt_type"]) |
1329 element_infos["elmt_type"] = FindTypeInfos(factory, element_infos["elmt_type"]) |
1330 if element_infos["type"] == ANY: |
1330 if element_infos["type"] == ANY: |
1331 element_infos["elmt_type"]["generate"](self, value) |
1331 element_infos["elmt_type"]["generate"](self, value) |
1332 |
1332 |
1333 elif name == "content" and element_infos["elmt_type"]["type"] == SIMPLETYPE: |
1333 elif name == "content" and element_infos["elmt_type"]["type"] == SIMPLETYPE: |
1334 self.text = element_infos["elmt_type"]["generate"](value) |
1334 self.text = element_infos["elmt_type"]["generate"](value) |
1335 |
1335 |
1336 else: |
1336 else: |
1337 prefix = ("%s:" % factory.TargetNamespace |
1337 prefix = ("%s:" % factory.TargetNamespace |
1338 if factory.TargetNamespace is not None else "") |
1338 if factory.TargetNamespace is not None else "") |
1339 element_xpath = (prefix + name |
1339 element_xpath = (prefix + name |
1340 if name != "content" |
1340 if name != "content" |
1341 else elements["content"]["elmt_type"]["choices_xpath"].path) |
1341 else elements["content"]["elmt_type"]["choices_xpath"].path) |
1342 |
1342 |
1343 for element in self.xpath(element_xpath, namespaces=factory.NSMAP): |
1343 for element in self.xpath(element_xpath, namespaces=factory.NSMAP): |
1344 self.remove(element) |
1344 self.remove(element) |
1345 |
1345 |
1346 if value is not None: |
1346 if value is not None: |
1347 element_idx = elements.keys().index(name) |
1347 element_idx = elements.keys().index(name) |
1348 if element_idx > 0: |
1348 if element_idx > 0: |
1349 previous_elements_xpath = "|".join(map( |
1349 previous_elements_xpath = "|".join(map( |
1350 lambda x: prefix + x |
1350 lambda x: prefix + x |
1351 if x != "content" |
1351 if x != "content" |
1352 else elements["content"]["elmt_type"]["choices_xpath"].path, |
1352 else elements["content"]["elmt_type"]["choices_xpath"].path, |
1353 elements.keys()[:element_idx])) |
1353 elements.keys()[:element_idx])) |
1354 |
1354 |
1355 insertion_point = len(self.xpath(previous_elements_xpath, namespaces=factory.NSMAP)) |
1355 insertion_point = len(self.xpath(previous_elements_xpath, namespaces=factory.NSMAP)) |
1356 else: |
1356 else: |
1357 insertion_point = 0 |
1357 insertion_point = 0 |
1358 |
1358 |
1359 if not isinstance(value, ListType): |
1359 if not isinstance(value, ListType): |
1360 value = [value] |
1360 value = [value] |
1361 |
1361 |
1362 for element in reversed(value): |
1362 for element in reversed(value): |
1363 if element_infos["elmt_type"]["type"] == SIMPLETYPE: |
1363 if element_infos["elmt_type"]["type"] == SIMPLETYPE: |
1364 tmp_element = etree.Element(factory.etreeNamespaceFormat % name) |
1364 tmp_element = etree.Element(factory.etreeNamespaceFormat % name) |
1365 tmp_element.text = element_infos["elmt_type"]["generate"](element) |
1365 tmp_element.text = element_infos["elmt_type"]["generate"](element) |
1366 element = tmp_element |
1366 element = tmp_element |
1367 self.insert(insertion_point, element) |
1367 self.insert(insertion_point, element) |
1368 |
1368 |
1369 elif classinfos.has_key("base"): |
1369 elif classinfos.has_key("base"): |
1370 return classinfos["base"].__setattr__(self, name, value) |
1370 return classinfos["base"].__setattr__(self, name, value) |
1371 |
1371 |
1372 else: |
1372 else: |
1373 raise AttributeError("'%s' can't have an attribute '%s'." % (self.__class__.__name__, name)) |
1373 raise AttributeError("'%s' can't have an attribute '%s'." % (self.__class__.__name__, name)) |
1374 |
1374 |
1375 return setattrMethod |
1375 return setattrMethod |
1376 |
1376 |
1377 def gettypeinfos(name, facets): |
1377 def gettypeinfos(name, facets): |
1378 if facets.has_key("enumeration") and facets["enumeration"][0] is not None: |
1378 if facets.has_key("enumeration") and facets["enumeration"][0] is not None: |
1379 return facets["enumeration"][0] |
1379 return facets["enumeration"][0] |
1396 attr_list = [] |
1396 attr_list = [] |
1397 if classinfos.has_key("base"): |
1397 if classinfos.has_key("base"): |
1398 attr_list.extend(classinfos["base"].getElementAttributes(self)) |
1398 attr_list.extend(classinfos["base"].getElementAttributes(self)) |
1399 for attr in classinfos["attributes"]: |
1399 for attr in classinfos["attributes"]: |
1400 if attr["use"] != "prohibited": |
1400 if attr["use"] != "prohibited": |
1401 attr_params = {"name" : attr["name"], "use" : attr["use"], |
1401 attr_params = {"name" : attr["name"], "use" : attr["use"], |
1402 "type" : gettypeinfos(attr["attr_type"]["basename"], attr["attr_type"]["facets"]), |
1402 "type" : gettypeinfos(attr["attr_type"]["basename"], attr["attr_type"]["facets"]), |
1403 "value" : getattr(self, attr["name"], "")} |
1403 "value" : getattr(self, attr["name"], "")} |
1404 attr_list.append(attr_params) |
1404 attr_list.append(attr_params) |
1405 return attr_list |
1405 return attr_list |
1406 return getElementAttributes |
1406 return getElementAttributes |
1407 |
1407 |
1408 def generateGetElementInfos(factory, classinfos): |
1408 def generateGetElementInfos(factory, classinfos): |
1409 attributes = dict([(attr["name"], attr) for attr in classinfos["attributes"] if attr["use"] != "prohibited"]) |
1409 attributes = dict([(attr["name"], attr) for attr in classinfos["attributes"] if attr["use"] != "prohibited"]) |
1410 elements = dict([(element["name"], element) for element in classinfos["elements"]]) |
1410 elements = dict([(element["name"], element) for element in classinfos["elements"]]) |
1411 |
1411 |
1412 def getElementInfos(self, name, path=None, derived=False): |
1412 def getElementInfos(self, name, path=None, derived=False): |
1413 attr_type = "element" |
1413 attr_type = "element" |
1414 value = None |
1414 value = None |
1415 use = "required" |
1415 use = "required" |
1416 children = [] |
1416 children = [] |
1417 if path is not None: |
1417 if path is not None: |
1418 parts = path.split(".", 1) |
1418 parts = path.split(".", 1) |
1419 if attributes.has_key(parts[0]): |
1419 if attributes.has_key(parts[0]): |
1420 if len(parts) != 1: |
1420 if len(parts) != 1: |
1421 raise ValueError("Wrong path!") |
1421 raise ValueError("Wrong path!") |
1422 attr_type = gettypeinfos(attributes[parts[0]]["attr_type"]["basename"], |
1422 attr_type = gettypeinfos(attributes[parts[0]]["attr_type"]["basename"], |
1423 attributes[parts[0]]["attr_type"]["facets"]) |
1423 attributes[parts[0]]["attr_type"]["facets"]) |
1424 value = getattr(self, parts[0], "") |
1424 value = getattr(self, parts[0], "") |
1425 elif elements.has_key(parts[0]): |
1425 elif elements.has_key(parts[0]): |
1426 if elements[parts[0]]["elmt_type"]["type"] == SIMPLETYPE: |
1426 if elements[parts[0]]["elmt_type"]["type"] == SIMPLETYPE: |
1427 if len(parts) != 1: |
1427 if len(parts) != 1: |
1428 raise ValueError("Wrong path!") |
1428 raise ValueError("Wrong path!") |
1429 attr_type = gettypeinfos(elements[parts[0]]["elmt_type"]["basename"], |
1429 attr_type = gettypeinfos(elements[parts[0]]["elmt_type"]["basename"], |
1430 elements[parts[0]]["elmt_type"]["facets"]) |
1430 elements[parts[0]]["elmt_type"]["facets"]) |
1431 value = getattr(self, parts[0], "") |
1431 value = getattr(self, parts[0], "") |
1432 elif parts[0] == "content": |
1432 elif parts[0] == "content": |
1433 return self.content.getElementInfos(self.content.getLocalTag(), path) |
1433 return self.content.getElementInfos(self.content.getLocalTag(), path) |
1434 else: |
1434 else: |
1461 else: |
1461 else: |
1462 value = self.content.getLocalTag() |
1462 value = self.content.getLocalTag() |
1463 if self.content is not None: |
1463 if self.content is not None: |
1464 children.extend(self.content.getElementInfos(value)["children"]) |
1464 children.extend(self.content.getElementInfos(value)["children"]) |
1465 elif element["elmt_type"]["type"] == SIMPLETYPE: |
1465 elif element["elmt_type"]["type"] == SIMPLETYPE: |
1466 children.append({"name": element_name, "require": element["minOccurs"] != 0, |
1466 children.append({"name": element_name, "require": element["minOccurs"] != 0, |
1467 "type": gettypeinfos(element["elmt_type"]["basename"], |
1467 "type": gettypeinfos(element["elmt_type"]["basename"], |
1468 element["elmt_type"]["facets"]), |
1468 element["elmt_type"]["facets"]), |
1469 "value": getattr(self, element_name, None)}) |
1469 "value": getattr(self, element_name, None)}) |
1470 else: |
1470 else: |
1471 instance = getattr(self, element_name, None) |
1471 instance = getattr(self, element_name, None) |
1472 if instance is None: |
1472 if instance is None: |
1476 return getElementInfos |
1476 return getElementInfos |
1477 |
1477 |
1478 def generateSetElementValue(factory, classinfos): |
1478 def generateSetElementValue(factory, classinfos): |
1479 attributes = dict([(attr["name"], attr) for attr in classinfos["attributes"] if attr["use"] != "prohibited"]) |
1479 attributes = dict([(attr["name"], attr) for attr in classinfos["attributes"] if attr["use"] != "prohibited"]) |
1480 elements = dict([(element["name"], element) for element in classinfos["elements"]]) |
1480 elements = dict([(element["name"], element) for element in classinfos["elements"]]) |
1481 |
1481 |
1482 def setElementValue(self, path, value): |
1482 def setElementValue(self, path, value): |
1483 if path is not None: |
1483 if path is not None: |
1484 parts = path.split(".", 1) |
1484 parts = path.split(".", 1) |
1485 if attributes.has_key(parts[0]): |
1485 if attributes.has_key(parts[0]): |
1486 if len(parts) != 1: |
1486 if len(parts) != 1: |
1487 raise ValueError("Wrong path!") |
1487 raise ValueError("Wrong path!") |
1488 if attributes[parts[0]]["attr_type"]["basename"] == "boolean": |
1488 if attributes[parts[0]]["attr_type"]["basename"] == "boolean": |
1489 setattr(self, parts[0], value) |
1489 setattr(self, parts[0], value) |
1490 elif attributes[parts[0]]["use"] == "optional" and value == "": |
1490 elif attributes[parts[0]]["use"] == "optional" and value == "": |
1491 if attributes[parts[0]].has_key("default"): |
1491 if attributes[parts[0]].has_key("default"): |
1492 setattr(self, parts[0], |
1492 setattr(self, parts[0], |
1493 attributes[parts[0]]["attr_type"]["extract"]( |
1493 attributes[parts[0]]["attr_type"]["extract"]( |
1494 attributes[parts[0]]["default"], False)) |
1494 attributes[parts[0]]["default"], False)) |
1495 else: |
1495 else: |
1496 setattr(self, parts[0], None) |
1496 setattr(self, parts[0], None) |
1497 else: |
1497 else: |
1678 """ |
1678 """ |
1679 |
1679 |
1680 NAMESPACE_PATTERN = re.compile("xmlns(?:\:[^\=]*)?=\"[^\"]*\" ") |
1680 NAMESPACE_PATTERN = re.compile("xmlns(?:\:[^\=]*)?=\"[^\"]*\" ") |
1681 |
1681 |
1682 class DefaultElementClass(etree.ElementBase): |
1682 class DefaultElementClass(etree.ElementBase): |
1683 |
1683 |
1684 StructurePattern = re.compile("$") |
1684 StructurePattern = re.compile("$") |
1685 |
1685 |
1686 def _init_(self): |
1686 def _init_(self): |
1687 pass |
1687 pass |
1688 |
1688 |
1689 def getLocalTag(self): |
1689 def getLocalTag(self): |
1690 return etree.QName(self.tag).localname |
1690 return etree.QName(self.tag).localname |
1691 |
1691 |
1692 def tostring(self): |
1692 def tostring(self): |
1693 return NAMESPACE_PATTERN.sub("", etree.tostring(self, pretty_print=True, encoding='utf-8')).decode('utf-8') |
1693 return NAMESPACE_PATTERN.sub("", etree.tostring(self, pretty_print=True, encoding='utf-8')).decode('utf-8') |
1694 |
1694 |
1695 class XMLElementClassLookUp(etree.PythonElementClassLookup): |
1695 class XMLElementClassLookUp(etree.PythonElementClassLookup): |
1696 |
1696 |
1697 def __init__(self, classes, *args, **kwargs): |
1697 def __init__(self, classes, *args, **kwargs): |
1698 etree.PythonElementClassLookup.__init__(self, *args, **kwargs) |
1698 etree.PythonElementClassLookup.__init__(self, *args, **kwargs) |
1699 self.LookUpClasses = classes |
1699 self.LookUpClasses = classes |
1700 |
1700 |
1701 def GetElementClass(self, element_tag, parent_tag=None, default=DefaultElementClass): |
1701 def GetElementClass(self, element_tag, parent_tag=None, default=DefaultElementClass): |
1702 element_class = self.LookUpClasses.get(element_tag, (default, None)) |
1702 element_class = self.LookUpClasses.get(element_tag, (default, None)) |
1703 if not isinstance(element_class, DictType): |
1703 if not isinstance(element_class, DictType): |
1704 if isinstance(element_class[0], (StringType, UnicodeType)): |
1704 if isinstance(element_class[0], (StringType, UnicodeType)): |
1705 return self.GetElementClass(element_class[0], default=default) |
1705 return self.GetElementClass(element_class[0], default=default) |
1706 return element_class[0] |
1706 return element_class[0] |
1707 |
1707 |
1708 element_with_parent_class = element_class.get(parent_tag, default) |
1708 element_with_parent_class = element_class.get(parent_tag, default) |
1709 if isinstance(element_with_parent_class, (StringType, UnicodeType)): |
1709 if isinstance(element_with_parent_class, (StringType, UnicodeType)): |
1710 return self.GetElementClass(element_with_parent_class, default=default) |
1710 return self.GetElementClass(element_with_parent_class, default=default) |
1711 return element_with_parent_class |
1711 return element_with_parent_class |
1712 |
1712 |
1713 def lookup(self, document, element): |
1713 def lookup(self, document, element): |
1714 parent = element.getparent() |
1714 parent = element.getparent() |
1715 element_class = self.GetElementClass(element.tag, |
1715 element_class = self.GetElementClass(element.tag, |
1716 parent.tag if parent is not None else None) |
1716 parent.tag if parent is not None else None) |
1717 if isinstance(element_class, ListType): |
1717 if isinstance(element_class, ListType): |
1718 children = "".join([ |
1718 children = "".join([ |
1719 "%s " % etree.QName(child.tag).localname |
1719 "%s " % etree.QName(child.tag).localname |
1720 for child in element]) |
1720 for child in element]) |
1739 for name, uri in namespaces.iteritems()} |
1739 for name, uri in namespaces.iteritems()} |
1740 else: |
1740 else: |
1741 self.RootNSMAP = namespaces |
1741 self.RootNSMAP = namespaces |
1742 self.BaseClass = base_class |
1742 self.BaseClass = base_class |
1743 self.XSDSchema = xsd_schema |
1743 self.XSDSchema = xsd_schema |
1744 |
1744 |
1745 def set_element_class_lookup(self, class_lookup): |
1745 def set_element_class_lookup(self, class_lookup): |
1746 etree.XMLParser.set_element_class_lookup(self, class_lookup) |
1746 etree.XMLParser.set_element_class_lookup(self, class_lookup) |
1747 self.ClassLookup = class_lookup |
1747 self.ClassLookup = class_lookup |
1748 |
1748 |
1749 def LoadXMLString(self, xml_string): |
1749 def LoadXMLString(self, xml_string): |
1750 tree = etree.fromstring(xml_string, self) |
1750 tree = etree.fromstring(xml_string, self) |
1751 if not self.XSDSchema.validate(tree): |
1751 if not self.XSDSchema.validate(tree): |
1752 error = self.XSDSchema.error_log.last_error |
1752 error = self.XSDSchema.error_log.last_error |
1753 return tree, (error.line, error.message) |
1753 return tree, (error.line, error.message) |
1754 return tree, None |
1754 return tree, None |
1755 |
1755 |
1756 def Dumps(self, xml_obj): |
1756 def Dumps(self, xml_obj): |
1757 return etree.tostring(xml_obj, encoding='utf-8') |
1757 return etree.tostring(xml_obj, encoding='utf-8') |
1758 |
1758 |
1759 def Loads(self, xml_string): |
1759 def Loads(self, xml_string): |
1760 return etree.fromstring(xml_string, self) |
1760 return etree.fromstring(xml_string, self) |
1761 |
1761 |
1762 def CreateRoot(self): |
1762 def CreateRoot(self): |
1763 if self.BaseClass is not None: |
1763 if self.BaseClass is not None: |
1764 root = self.makeelement( |
1764 root = self.makeelement( |
1765 self.DefaultNamespaceFormat % self.BaseClass[0], |
1765 self.DefaultNamespaceFormat % self.BaseClass[0], |
1766 nsmap=self.RootNSMAP) |
1766 nsmap=self.RootNSMAP) |
1767 root._init_() |
1767 root._init_() |
1768 return root |
1768 return root |
1769 return None |
1769 return None |
1770 |
1770 |
1771 def GetElementClass(self, element_tag, parent_tag=None): |
1771 def GetElementClass(self, element_tag, parent_tag=None): |
1772 return self.ClassLookup.GetElementClass( |
1772 return self.ClassLookup.GetElementClass( |
1773 self.DefaultNamespaceFormat % element_tag, |
1773 self.DefaultNamespaceFormat % element_tag, |
1774 self.DefaultNamespaceFormat % parent_tag |
1774 self.DefaultNamespaceFormat % parent_tag |
1775 if parent_tag is not None else parent_tag, |
1775 if parent_tag is not None else parent_tag, |
1776 None) |
1776 None) |
1777 |
1777 |
1778 def CreateElement(self, element_tag, parent_tag=None, class_idx=None): |
1778 def CreateElement(self, element_tag, parent_tag=None, class_idx=None): |
1779 element_class = self.GetElementClass(element_tag, parent_tag) |
1779 element_class = self.GetElementClass(element_tag, parent_tag) |
1780 if isinstance(element_class, ListType): |
1780 if isinstance(element_class, ListType): |
1781 if class_idx is not None and class_idx < len(element_class): |
1781 if class_idx is not None and class_idx < len(element_class): |
1782 new_element = element_class[class_idx]() |
1782 new_element = element_class[class_idx]() |
1785 else: |
1785 else: |
1786 new_element = element_class() |
1786 new_element = element_class() |
1787 DefaultElementClass.__setattr__(new_element, "tag", self.DefaultNamespaceFormat % element_tag) |
1787 DefaultElementClass.__setattr__(new_element, "tag", self.DefaultNamespaceFormat % element_tag) |
1788 new_element._init_() |
1788 new_element._init_() |
1789 return new_element |
1789 return new_element |
1790 |
1790 |
1791 def GenerateParser(factory, xsdstring): |
1791 def GenerateParser(factory, xsdstring): |
1792 ComputedClasses = factory.CreateClasses() |
1792 ComputedClasses = factory.CreateClasses() |
1793 |
1793 |
1794 if factory.FileName is not None: |
1794 if factory.FileName is not None: |
1795 ComputedClasses = ComputedClasses[factory.FileName] |
1795 ComputedClasses = ComputedClasses[factory.FileName] |
1796 BaseClass = [(name, XSDclass) for name, XSDclass in ComputedClasses.items() if XSDclass.IsBaseClass] |
1796 BaseClass = [(name, XSDclass) for name, XSDclass in ComputedClasses.items() if XSDclass.IsBaseClass] |
1797 |
1797 |
1798 parser = XMLClassParser( |
1798 parser = XMLClassParser( |
1799 factory.NSMAP, |
1799 factory.NSMAP, |
1800 factory.etreeNamespaceFormat, |
1800 factory.etreeNamespaceFormat, |
1801 BaseClass[0] if len(BaseClass) == 1 else None, |
1801 BaseClass[0] if len(BaseClass) == 1 else None, |
1802 etree.XMLSchema(etree.fromstring(xsdstring)), |
1802 etree.XMLSchema(etree.fromstring(xsdstring)), |
1803 strip_cdata = False, remove_blank_text=True) |
1803 strip_cdata = False, remove_blank_text=True) |
1804 class_lookup = XMLElementClassLookUp(factory.ComputedClassesLookUp) |
1804 class_lookup = XMLElementClassLookUp(factory.ComputedClassesLookUp) |
1805 parser.set_element_class_lookup(class_lookup) |
1805 parser.set_element_class_lookup(class_lookup) |
1806 |
1806 |
1807 return parser |
1807 return parser |
1808 |
|