Skip to content

mixins

xsdata.codegen.mappers.mixins

RawDocumentMapper

Mixin class for raw json/xml documents.

Source code in xsdata/codegen/mappers/mixins.py
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
class RawDocumentMapper:
    """Mixin class for raw json/xml documents."""

    @classmethod
    def build_attr(
        cls,
        target: Class,
        qname: str,
        attr_type: AttrType,
        parent_namespace: Optional[str] = None,
        tag: str = Tag.ELEMENT,
        sequence: int = 0,
    ):
        """Build an attr for the given class instance.

        Args:
            target: The target class instance
            qname: The attr qualified name
            attr_type: The attr type instance
            parent_namespace: The parent namespace
            tag: The attr tag
            sequence: The attr sequence number
        """
        namespace, name = split_qname(qname)
        namespace = cls.select_namespace(namespace, parent_namespace, tag)
        index = len(target.attrs)

        attr = Attr(index=index, name=name, tag=tag, namespace=namespace)
        attr.types.append(attr_type)

        if sequence:
            attr.restrictions.path.append(("s", sequence, 1, sys.maxsize))

        attr.restrictions.min_occurs = 1
        attr.restrictions.max_occurs = 1
        cls.add_attribute(target, attr)

    @classmethod
    def build_attr_type(cls, qname: str, value: Any) -> AttrType:
        """Build an attribute type for the given attribute name and value.

        Args:
            qname: The attr qualified name
            value: The attr value

        Returns:
           The new attr type instance.
        """

        def match_type(val: Any) -> DataType:
            if not isinstance(val, str):
                return DataType.from_value(val)

            for tp in converter.explicit_types():
                if converter.test(val, [tp], strict=True):
                    return DataType.from_type(tp)

            return DataType.STRING

        if qname == QNames.XSI_TYPE:
            data_type = DataType.QNAME
        elif value is None or value == "":
            data_type = DataType.ANY_SIMPLE_TYPE
        else:
            data_type = match_type(value)

        return AttrType(qname=str(data_type), native=True)

    @classmethod
    def select_namespace(
        cls,
        namespace: Optional[str],
        parent_namespace: Optional[str],
        tag: str = Tag.ELEMENT,
    ) -> Optional[str]:
        """Select the namespace based on the tag and namespace.

        Args:
            namespace: The current namespace
            parent_namespace: The parent namespace
            tag: The tag name

        Returns:
            Optional[str]: The selected namespace.
        """
        if tag == Tag.ATTRIBUTE:
            return namespace

        if namespace is None and parent_namespace is not None:
            return ""

        return namespace

    @classmethod
    def add_attribute(cls, target: Class, attr: Attr):
        """Add an attr to the target class instance.

        Args:
            target: The target class instance
            attr (Attr): The attribute to be added.
        """
        pos = collections.find(target.attrs, attr)

        if pos > -1:
            existing = target.attrs[pos]
            existing.restrictions.max_occurs = sys.maxsize
            existing.types.extend(attr.types)
            existing.types = collections.unique_sequence(existing.types, key="qname")
        else:
            target.attrs.append(attr)

build_attr(target, qname, attr_type, parent_namespace=None, tag=Tag.ELEMENT, sequence=0) classmethod

Build an attr for the given class instance.

Parameters:

Name Type Description Default
target Class

The target class instance

required
qname str

The attr qualified name

required
attr_type AttrType

The attr type instance

required
parent_namespace Optional[str]

The parent namespace

None
tag str

The attr tag

ELEMENT
sequence int

The attr sequence number

0
Source code in xsdata/codegen/mappers/mixins.py
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
@classmethod
def build_attr(
    cls,
    target: Class,
    qname: str,
    attr_type: AttrType,
    parent_namespace: Optional[str] = None,
    tag: str = Tag.ELEMENT,
    sequence: int = 0,
):
    """Build an attr for the given class instance.

    Args:
        target: The target class instance
        qname: The attr qualified name
        attr_type: The attr type instance
        parent_namespace: The parent namespace
        tag: The attr tag
        sequence: The attr sequence number
    """
    namespace, name = split_qname(qname)
    namespace = cls.select_namespace(namespace, parent_namespace, tag)
    index = len(target.attrs)

    attr = Attr(index=index, name=name, tag=tag, namespace=namespace)
    attr.types.append(attr_type)

    if sequence:
        attr.restrictions.path.append(("s", sequence, 1, sys.maxsize))

    attr.restrictions.min_occurs = 1
    attr.restrictions.max_occurs = 1
    cls.add_attribute(target, attr)

build_attr_type(qname, value) classmethod

Build an attribute type for the given attribute name and value.

Parameters:

Name Type Description Default
qname str

The attr qualified name

required
value Any

The attr value

required

Returns:

Type Description
AttrType

The new attr type instance.

Source code in xsdata/codegen/mappers/mixins.py
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
@classmethod
def build_attr_type(cls, qname: str, value: Any) -> AttrType:
    """Build an attribute type for the given attribute name and value.

    Args:
        qname: The attr qualified name
        value: The attr value

    Returns:
       The new attr type instance.
    """

    def match_type(val: Any) -> DataType:
        if not isinstance(val, str):
            return DataType.from_value(val)

        for tp in converter.explicit_types():
            if converter.test(val, [tp], strict=True):
                return DataType.from_type(tp)

        return DataType.STRING

    if qname == QNames.XSI_TYPE:
        data_type = DataType.QNAME
    elif value is None or value == "":
        data_type = DataType.ANY_SIMPLE_TYPE
    else:
        data_type = match_type(value)

    return AttrType(qname=str(data_type), native=True)

select_namespace(namespace, parent_namespace, tag=Tag.ELEMENT) classmethod

Select the namespace based on the tag and namespace.

Parameters:

Name Type Description Default
namespace Optional[str]

The current namespace

required
parent_namespace Optional[str]

The parent namespace

required
tag str

The tag name

ELEMENT

Returns:

Type Description
Optional[str]

Optional[str]: The selected namespace.

Source code in xsdata/codegen/mappers/mixins.py
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
@classmethod
def select_namespace(
    cls,
    namespace: Optional[str],
    parent_namespace: Optional[str],
    tag: str = Tag.ELEMENT,
) -> Optional[str]:
    """Select the namespace based on the tag and namespace.

    Args:
        namespace: The current namespace
        parent_namespace: The parent namespace
        tag: The tag name

    Returns:
        Optional[str]: The selected namespace.
    """
    if tag == Tag.ATTRIBUTE:
        return namespace

    if namespace is None and parent_namespace is not None:
        return ""

    return namespace

add_attribute(target, attr) classmethod

Add an attr to the target class instance.

Parameters:

Name Type Description Default
target Class

The target class instance

required
attr Attr

The attribute to be added.

required
Source code in xsdata/codegen/mappers/mixins.py
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
@classmethod
def add_attribute(cls, target: Class, attr: Attr):
    """Add an attr to the target class instance.

    Args:
        target: The target class instance
        attr (Attr): The attribute to be added.
    """
    pos = collections.find(target.attrs, attr)

    if pos > -1:
        existing = target.attrs[pos]
        existing.restrictions.max_occurs = sys.maxsize
        existing.types.extend(attr.types)
        existing.types = collections.unique_sequence(existing.types, key="qname")
    else:
        target.attrs.append(attr)