Исходный код EJIO.utils.serialization.implementations.xml_serializer
## /utils/serialization/implementations/xml_serializer.py
import xmltodict
from os.path import exists
from typing import Any
from ..serializer import Serializer
from ..serializer_registry import register_serializer
from ..err import SerializationError
__all__ = [
'XMLSerializer',
]
[документация]
@register_serializer('xml')
class XMLSerializer(Serializer):
"""
Реализация интерфейса Serializer для формата XML на базе библиотеки xmltodict.
"""
__slots__ = ()
[документация]
@staticmethod
def serialize[T](data: dict[str, T], /, **kwargs: Any) -> str:
"""
Превращает словарь в XML строку, оборачивая её в корневой тег root.
:param data: Сериализуемый словарь.
:param kwargs: Ключевые параметры для сереализатора.
:return: XML-строка.
:raises SerializationError: При ошибках сериализации.
"""
try:
# XML требует ровно один корневой элемент верхнего уровня
wrapped_data = {"root": data}
# xmltodict поддерживает форматирование через параметр full_document
return xmltodict.unparse(wrapped_data, **kwargs)
except Exception as e:
raise SerializationError("Serialization to xml failed") from e
[документация]
@staticmethod
def deserialize[T](data: str, /, **kwargs: Any) -> dict[str, T]:
"""
Парсит XML строку обратно в словарь, очищая корневой тег root.
:param data: XML-строка.
:param kwargs: Ключевые параметры для сереализатора.
:return: Десериализованный словарь.
:raises SerializationError: При ошибках десериализации.
"""
try:
parsed = xmltodict.parse(data, **kwargs)
# Извлекаем данные из корневого тега root, возвращая исходный dict
if "root" in parsed:
return parsed["root"] # type: ignore[return-value]
return parsed # type: ignore[return-value]
except Exception as e:
raise SerializationError("Deserialization from xml failed") from e
[документация]
@staticmethod
def save[T](data: dict[str, T], filename: str, /, **kwargs: Any) -> None:
"""
Сохранить словарь в XML-файл.
:param data: Сериализуемый словарь.
:param filename: Путь к файлу для сохранения.
:param kwargs: Ключевые параметры для сереализатора.
:raises SerializationError: При ошибках сериализации.
"""
try:
xml_string = XMLSerializer.serialize(data, **kwargs)
with open(filename, 'w', encoding='utf-8') as f:
f.write(xml_string)
except (IOError, OSError, SerializationError) as e:
raise SerializationError("Failed to serialize data to xml file") from e
[документация]
@staticmethod
def load[T](filename: str, /, **kwargs: Any) -> dict[str, T]:
"""
Загрузить словарь из XML-файла.
:param filename: Путь к файлу для загрузки.
:param kwargs: Ключевые параметры для сереализатора.
:return: Словарь, полученный из файла.
:raises SerializationError: При ошибках десериализации.
"""
try:
if not exists(filename):
raise FileNotFoundError(f"File {filename} not found")
with open(filename, 'r', encoding='utf-8') as f:
data = f.read()
return XMLSerializer.deserialize(data, **kwargs)
except (IOError, OSError, FileNotFoundError, SerializationError) as e:
raise SerializationError("Failed to deserialize data from xml file") from e