Skip to content

# xml

## `xsdata.formats.dataclass.parsers.xml`

### `XmlParser` `dataclass`

Bases: `NodeParser`

Default Xml parser for data classes.

Parameters:

Name | Type | Description | Default
--- | --- | --- | ---
`config` | `ParserConfig` | The parser config instance | `ParserConfig()`
`context` | `XmlContext` | The xml context instance | `XmlContext()`
`handler` | `type[XmlHandler]` | The xml handler class | `default_handler()`

Attributes:

Name | Type | Description
--- | --- | ---
`ns_map` | `dict[str | None, str]` | The parsed namespace prefix-URI map

Source code in `xsdata/formats/dataclass/parsers/xml.py`

    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25

    @dataclass
    class XmlParser(NodeParser):
        """Default Xml parser for data classes.

        Args:
            config: The parser config instance
            context: The xml context instance
            handler: The xml handler class

        Attributes:
            ns_map: The parsed namespace prefix-URI map
        """

        handler: type[XmlHandler] = field(default=default_handler())

### `UserXmlParser` `dataclass`

Bases: `NodeParser`

Xml parser for dataclasses with hooks to events.

The event hooks allow custom parsers to inject custom logic between the start/end element events.

Parameters:

Name | Type | Description | Default
--- | --- | --- | ---
`config` | `ParserConfig` | The parser config instance | `ParserConfig()`
`context` | `XmlContext` | The xml context instance | `XmlContext()`
`handler` | `type[XmlHandler]` | The xml handler class | `default_handler()`

Attributes:

Name | Type | Description
--- | --- | ---
`ns_map` | `dict[str | None, str]` | The parsed namespace prefix-URI map
`hooks_cache` | `dict` | The hooks cache is used to avoid inspecting the class for custom methods on duplicate events.

Source code in `xsdata/formats/dataclass/parsers/xml.py`

     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

    @dataclass
    class UserXmlParser(NodeParser):
        """Xml parser for dataclasses with hooks to events.

        The event hooks allow custom parsers to inject custom
        logic between the start/end element events.

        Args:
            config: The parser config instance
            context: The xml context instance
            handler: The xml handler class

        Attributes:
            ns_map: The parsed namespace prefix-URI map
            hooks_cache: The hooks cache is used to avoid
                inspecting the class for custom methods
                on duplicate events.
        """

        handler: type[XmlHandler] = field(default=default_handler())
        hooks_cache: dict = field(init=False, default_factory=dict)

        def start(
            self,
            clazz: type | None,
            queue: list[XmlNode],
            objects: list[Parsed],
            qname: str,
            attrs: dict,
            ns_map: dict,
        ) -> None:
            """Build and queue the XmlNode for the starting element.

            Override to emit the start element event.

            Args:
                clazz: The target class type, auto locate if omitted
                queue: The XmlNode queue list
                objects: The list of all intermediate parsed objects
                qname: The element qualified name
                attrs: The element attributes
                ns_map: The element namespace prefix-URI map
            """
            super().start(clazz, queue, objects, qname, attrs, ns_map)
            self.emit_event(EventType.START, qname, attrs=attrs)

        def end(
            self,
            queue: list[XmlNode],
            objects: list[Parsed],
            qname: str,
            text: str | None,
            tail: str | None,
        ) -> bool:
            """Parse the last xml node and bind any intermediate objects.

            Override to emit the end element event if the binding process
            is successful.

            Args:
                queue: The XmlNode queue list
                objects: The list of all intermediate parsed objects
                qname: The element qualified name
                text: The element text content
                tail: The element tail content

            Returns:
                Whether the binding process was successful.
            """
            result = super().end(queue, objects, qname, text, tail)
            if result:
                self.emit_event(EventType.END, qname, obj=objects[-1][1])
            return result

        def emit_event(self, event: str, name: str, **kwargs: Any) -> None:
            """Propagate event to subclasses.

            Match event and name to a subclass method and trigger it with
            any input keyword arguments.

            Example::
                event=start, name={urn}bookTitle -> start_booking_title(**kwargs)

            Args:
                event: The event type start|end
                name: The qualified name of the element
                kwargs: Additional keyword arguments passed to the hooks
            """
            key = (event, name)
            if key not in self.hooks_cache:
                method_name = f"{event}_{snake_case(local_name(name))}"
                self.hooks_cache[key] = getattr(self, method_name, None)

            method = self.hooks_cache[key]
            if method:
                method(**kwargs)

#### `start(clazz, queue, objects, qname, attrs, ns_map)`

Build and queue the XmlNode for the starting element.

Override to emit the start element event.

Parameters:

Name | Type | Description | Default
--- | --- | --- | ---
`clazz` | `type | None` | The target class type, auto locate if omitted | required
`queue` | `list[XmlNode]` | The XmlNode queue list | required
`objects` | `list[Parsed]` | The list of all intermediate parsed objects | required
`qname` | `str` | The element qualified name | required
`attrs` | `dict` | The element attributes | required
`ns_map` | `dict` | The element namespace prefix-URI map | required

Source code in `xsdata/formats/dataclass/parsers/xml.py`

    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72

    def start(
        self,
        clazz: type | None,
        queue: list[XmlNode],
        objects: list[Parsed],
        qname: str,
        attrs: dict,
        ns_map: dict,
    ) -> None:
        """Build and queue the XmlNode for the starting element.

        Override to emit the start element event.

        Args:
            clazz: The target class type, auto locate if omitted
            queue: The XmlNode queue list
            objects: The list of all intermediate parsed objects
            qname: The element qualified name
            attrs: The element attributes
            ns_map: The element namespace prefix-URI map
        """
        super().start(clazz, queue, objects, qname, attrs, ns_map)
        self.emit_event(EventType.START, qname, attrs=attrs)

#### `end(queue, objects, qname, text, tail)`

Parse the last xml node and bind any intermediate objects.

Override to emit the end element event if the binding process is successful.

Parameters:

Name | Type | Description | Default
--- | --- | --- | ---
`queue` | `list[XmlNode]` | The XmlNode queue list | required
`objects` | `list[Parsed]` | The list of all intermediate parsed objects | required
`qname` | `str` | The element qualified name | required
`text` | `str | None` | The element text content | required
`tail` | `str | None` | The element tail content | required

Returns:

Type | Description
--- | ---
`bool` | Whether the binding process was successful.

Source code in `xsdata/formats/dataclass/parsers/xml.py`

     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

    def end(
        self,
        queue: list[XmlNode],
        objects: list[Parsed],
        qname: str,
        text: str | None,
        tail: str | None,
    ) -> bool:
        """Parse the last xml node and bind any intermediate objects.

        Override to emit the end element event if the binding process
        is successful.

        Args:
            queue: The XmlNode queue list
            objects: The list of all intermediate parsed objects
            qname: The element qualified name
            text: The element text content
            tail: The element tail content

        Returns:
            Whether the binding process was successful.
        """
        result = super().end(queue, objects, qname, text, tail)
        if result:
            self.emit_event(EventType.END, qname, obj=objects[-1][1])
        return result

#### `emit_event(event, name, **kwargs)`

Propagate event to subclasses.

Match event and name to a subclass method and trigger it with any input keyword arguments.

Example:: event=start, name={urn}bookTitle -> start_booking_title(**kwargs)

Parameters:

Name | Type | Description | Default
--- | --- | --- | ---
`event` | `str` | The event type start|end | required
`name` | `str` | The qualified name of the element | required
`kwargs` | `Any` | Additional keyword arguments passed to the hooks | `{}`

Source code in `xsdata/formats/dataclass/parsers/xml.py`

    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123

    def emit_event(self, event: str, name: str, **kwargs: Any) -> None:
        """Propagate event to subclasses.

        Match event and name to a subclass method and trigger it with
        any input keyword arguments.

        Example::
            event=start, name={urn}bookTitle -> start_booking_title(**kwargs)

        Args:
            event: The event type start|end
            name: The qualified name of the element
            kwargs: Additional keyword arguments passed to the hooks
        """
        key = (event, name)
        if key not in self.hooks_cache:
            method_name = f"{event}_{snake_case(local_name(name))}"
            self.hooks_cache[key] = getattr(self, method_name, None)

        method = self.hooks_cache[key]
        if method:
            method(**kwargs)