File: dict.py

package info (click to toggle)
python-xsdata 24.1-2
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 2,936 kB
  • sloc: python: 29,257; xml: 404; makefile: 27; sh: 6
file content (46 lines) | stat: -rw-r--r-- 1,713 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
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
import sys
from typing import Any, Dict, List

from xsdata.codegen.mappers.element import ElementMapper
from xsdata.codegen.models import AttrType, Class
from xsdata.codegen.utils import ClassUtils
from xsdata.models.enums import Tag


class DictMapper:
    """Map a dictionary to classes, extensions and attributes."""

    @classmethod
    def map(cls, data: Dict, name: str, location: str) -> List[Class]:
        """Convert a dictionary to a list of codegen classes."""
        target = cls.build_class(data, name)
        return list(ClassUtils.flatten(target, f"{location}/{name}"))

    @classmethod
    def build_class(cls, data: Dict, name: str) -> Class:
        target = Class(qname=name, tag=Tag.ELEMENT, location="")

        for key, value in data.items():
            cls.build_class_attribute(target, key, value)

        return target

    @classmethod
    def build_class_attribute(cls, target: Class, name: str, value: Any):
        if isinstance(value, list):
            if not value:
                cls.build_class_attribute(target, name, None)
                target.attrs[-1].restrictions.max_occurs = sys.maxsize
            else:
                for val in value:
                    cls.build_class_attribute(target, name, val)
                    target.attrs[-1].restrictions.max_occurs = sys.maxsize
        else:
            if isinstance(value, dict):
                inner = cls.build_class(value, name)
                attr_type = AttrType(qname=inner.qname, forward=True)
                target.inner.append(inner)
            else:
                attr_type = ElementMapper.build_attribute_type(name, value)

            ElementMapper.build_attribute(target, name, attr_type)