def _make_type(self, value, type): ''' Parse value and convert it to type ''' iselem = False if ET.iselement(value): iselem = True xtype = value.get(xsi_type) if xtype: xtype = ns.expand(xtype, value.nsmap) (prefix, t) = ns.split(xtype) if prefix == ns.XS: type = 'xs:'+t else: type = xtype if value.get(xsi_nil) == 'true': return None if type.startswith('xs:'): if iselem: value = value.text c = converter(type) if value is not None and not c.check(value): value = c.fromstr(value) else: if value == "": value = None value = self.__builder__.factory(type)(value, __relax__=self.__relax__) return value
def _make_type(self, value, type): ''' Parse value and convert it to type ''' iselem = False if ET.iselement(value): iselem = True xtype = value.get(xsi_type) if xtype: xtype = ns.expand(xtype, value.nsmap) (prefix, t) = ns.split(xtype) if prefix == ns.XS: type = 'xs:' + t else: type = xtype if value.get(xsi_nil) == 'true': return None if type.startswith('xs:'): if iselem: value = value.text c = converter(type) if value is not None and not c.check(value): value = c.fromstr(value) else: if value == "": value = None value = self.__builder__.factory(type)(value, __relax__=self.__relax__) return value
def xs_element(self, node, **kwargs): ref = node.get('ref') default = None min = self.minOccurs max = self.maxOccurs nil = 'false' if ref is not None: refnode = self.loader.element(self.nsexpand(ref)) name = refnode.get('name') type = refnode.get('type') default = refnode.get('default', default) min = refnode.get('minOccurs', min) max = refnode.get('maxOccurs', max) nil = refnode.get('nillable', nil) else: name = node.get('name') type = node.get('type') default = node.get('default', default) min = self.tryint(node.get('minOccurs', min)) max = self.tryint(node.get('maxOccurs', max)) nil = int(converter('xs:boolean').fromstr(node.get('nillable', nil))) if type is None: if self.typename: type = '%s_%s' % (self.typename, name) else: type = self.nsexpand(name) self.process(node.getchildren(), name=type) else: type = self.nsexpand(type, target=False) (namespace, type) = self.nssplit(type) if namespace == ns.XS: type = 'xs:%s' % type else: type = '{%s}%s' % (namespace, type) self.template.append( (name, type, default, (min, max), self.flags | nil))
def xs_element(self, node, **kwargs): ref = node.get('ref') default = None min = self.minOccurs max = self.maxOccurs nil = 'false' if ref is not None: refnode = self.loader.element(self.nsexpand(ref)) name = refnode.get('name') type = refnode.get('type') default = refnode.get('default', default) min = refnode.get('minOccurs', min) max = refnode.get('maxOccurs', max) nil = refnode.get('nillable', nil) else: name = node.get('name') type = node.get('type') default = node.get('default', default) min = self.tryint(node.get('minOccurs', min)) max = self.tryint(node.get('maxOccurs', max)) nil = int(converter('xs:boolean').fromstr(node.get('nillable', nil))) if type is None: if self.typename: type = '%s_%s' % (self.typename, name) else: type = self.nsexpand(name) self.process(node.getchildren(), name=type) else: type = self.nsexpand(type, target=False) (namespace, type) = self.nssplit(type) if namespace == ns.XS: type = 'xs:%s' % type else: type = '{%s}%s' % (namespace, type) self.template.append((name, type, default, (min, max), self.flags | nil))
def __xml__(self, tag=None, node=None, nsmap=None): lat = len(self.__attrchar__) done = [] extra = False if tag is None: tag = self.__class__.__name__ tag = self.__nsx__(tag) if node is None: node = ET.Element(tag, nsmap=nsmap) # Construct reverse namespace map for doing xsi:type rmap = dict((v,k) for k, v in node.nsmap.items() if k is not None) # Iterate over the template to construct the XML representation. for (name, type, default, minmax, flags) in self.__template__: # If this field is an "xs:any" node, note it for later and skip if (flags & ANY): extra = True continue # If the field is choice/optional and doesn't exist, skip it if ((flags & CHOICE) or minmax[0] == 0) and name not in self: continue # Get the value value = self[name] done.append(name) if value is None and minmax[0] == 0 and not (flags & XSINIL): # Skip fields that are none and don't have to exist, as long # as they aren't nillable continue elif (flags & ATTRIBUTE): # Handle attributes. Skip attributes that are optional value = converter(type).tostr(value) if value is None: value = '' if value is not None or minmax[0]: node.set(self.__nsx__(name[lat:], flags & QUALIFIED), value) continue elif (flags & PROPERTY): # Property node.text = converter(type).tostr(value) continue qname = self.__nsx__(name) if not isinstance(value, (list, tuple)): value = [value] for v in value: if v is None and (flags & XSINIL): # Nil node n = ET.Element(qname, xsi_nil_true) node.append(n) elif ET.iselement(v): # User supplied XML Elements, so just add them node.append(v) elif type.startswith('xs:'): # Primitive type n = ET.Element(qname) n.text = converter(type).tostr(v) node.append(n) elif flags & SIMPLE: # Primitive type type = self.__builder__.factory(type).__simple__ n = ET.Element(qname) n.text = converter(type).tostr(v) node.append(n) elif isinstance(v, DynamicObject): # Dynamic object or subclass, so marshall and append n = v.__xml__(name) if type != v.__class__.__name__: (namespace, datatype) = ns.split(v.__class__.__name__) n.set(xsi_type, '%s:%s' % (rmap[namespace], datatype)) node.append(n) elif v == '': # Carry-over for dealing with SUDS bug pass else: if not self.__relax__: raise TypeError('Unknown type', name, type) # If there was an xs:any node, fall back to the schemaless marshaller # in the base class if extra: DynamicObject.__xml__(self, tag, node, ignore=done) return node
def __xml__(self, tag=None, node=None, nsmap=None): lat = len(self.__attrchar__) done = [] extra = False if tag is None: tag = self.__class__.__name__ tag = self.__nsx__(tag) if node is None: node = ET.Element(tag, nsmap=nsmap) # Construct reverse namespace map for doing xsi:type rmap = dict((v, k) for k, v in node.nsmap.items() if k is not None) # Iterate over the template to construct the XML representation. for (name, type, default, minmax, flags) in self.__template__: # If this field is an "xs:any" node, note it for later and skip if (flags & ANY): extra = True continue # If the field is choice/optional and doesn't exist, skip it if ((flags & CHOICE) or minmax[0] == 0) and name not in self: continue # Get the value value = self[name] done.append(name) if value is None and minmax[0] == 0 and not (flags & XSINIL): # Skip fields that are none and don't have to exist, as long # as they aren't nillable continue elif (flags & ATTRIBUTE): # Handle attributes. Skip attributes that are optional value = converter(type).tostr(value) if value is None: value = '' if value is not None or minmax[0]: node.set(self.__nsx__(name[lat:], flags & QUALIFIED), value) continue elif (flags & PROPERTY): # Property node.text = converter(type).tostr(value) continue qname = self.__nsx__(name) if not isinstance(value, (list, tuple)): value = [value] for v in value: if v is None and (flags & XSINIL): # Nil node n = ET.Element(qname, xsi_nil_true) node.append(n) elif ET.iselement(v): # User supplied XML Elements, so just add them node.append(v) elif type.startswith('xs:'): # Primitive type n = ET.Element(qname) n.text = converter(type).tostr(v) node.append(n) elif flags & SIMPLE: # Primitive type type = self.__builder__.factory(type).__simple__ n = ET.Element(qname) n.text = converter(type).tostr(v) node.append(n) elif isinstance(v, DynamicObject): # Dynamic object or subclass, so marshall and append n = v.__xml__(name) if type != v.__class__.__name__: (namespace, datatype) = ns.split(v.__class__.__name__) n.set(xsi_type, '%s:%s' % (rmap[namespace], datatype)) node.append(n) elif v == '': # Carry-over for dealing with SUDS bug pass else: if not self.__relax__: raise TypeError('Unknown type', name, type) # If there was an xs:any node, fall back to the schemaless marshaller # in the base class if extra: DynamicObject.__xml__(self, tag, node, ignore=done) return node