Skip to content

mixins

xsdata.codegen.mappers.mixins

RawDocumentMapper

Mixin class for raw json/xml documents.

Source code in xsdata/codegen/mappers/mixins.py
 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
121
122
123
124
125
126
127
128
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,
        value: Any = _UNSET,
    ):
        """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
            value: The attr sample value
        """
        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

        if value is None:
            attr.restrictions.min_occurs = 0

        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, value=_UNSET) 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
value Any

The attr sample value

_UNSET
Source code in xsdata/codegen/mappers/mixins.py
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
@classmethod
def build_attr(
    cls,
    target: Class,
    qname: str,
    attr_type: AttrType,
    parent_namespace: Optional[str] = None,
    tag: str = Tag.ELEMENT,
    sequence: int = 0,
    value: Any = _UNSET,
):
    """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
        value: The attr sample value
    """
    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

    if value is None:
        attr.restrictions.min_occurs = 0

    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
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
@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
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
@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
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
@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)