Esempio n. 1
0
    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
Esempio n. 2
0
    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
Esempio n. 3
0
    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))
Esempio n. 4
0
    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))
Esempio n. 5
0
    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
Esempio n. 6
0
    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