From 6042331dbae80329d1ecc1aba5e3289b3273de8f Mon Sep 17 00:00:00 2001 From: ulleo Date: Fri, 24 Jul 2026 18:07:41 +0800 Subject: [PATCH] refactor: replace dicttoxml with stdlib implementation to avoid GPL license risk --- .../apps/data_training/curd/data_training.py | 12 +---- backend/apps/terminology/curd/terminology.py | 12 +---- backend/common/utils/dict_to_xml.py | 49 +++++++++++++++++++ backend/pyproject.toml | 1 - 4 files changed, 53 insertions(+), 21 deletions(-) create mode 100644 backend/common/utils/dict_to_xml.py diff --git a/backend/apps/data_training/curd/data_training.py b/backend/apps/data_training/curd/data_training.py index 3c775638..5507adef 100644 --- a/backend/apps/data_training/curd/data_training.py +++ b/backend/apps/data_training/curd/data_training.py @@ -1,10 +1,8 @@ import datetime -import logging import traceback from typing import List, Optional from xml.dom.minidom import parseString -import dicttoxml from sqlalchemy import and_, select, func, delete, update, or_ from sqlalchemy import text @@ -15,6 +13,7 @@ from apps.template.generate_chart.generator import get_base_data_training_template from common.core.config import settings from common.core.deps import SessionDep, Trans +from common.utils.dict_to_xml import dict_to_xml from common.utils.embedding_threads import run_save_data_training_embeddings @@ -594,14 +593,7 @@ def select_training_by_question(session: SessionDep, question: str, oid: int, da def to_xml_string(_dict: list[dict] | dict, root: str = 'sql-examples') -> str: item_name_func = lambda x: 'sql-example' if x == 'sql-examples' else 'item' - dicttoxml.LOG.setLevel(logging.ERROR) - xml = dicttoxml.dicttoxml(_dict, - cdata=['question', 'suggestion-answer'], - custom_root=root, - item_func=item_name_func, - xml_declaration=False, - encoding='utf-8', - attr_type=False).decode('utf-8') + xml = dict_to_xml(_dict, root_name=root, item_func=item_name_func) pretty_xml = parseString(xml).toprettyxml() if pretty_xml.startswith(' str: item_name_func = lambda x: 'terminology' if x == 'terminologies' else 'word' if x == 'words' else 'item' - dicttoxml.LOG.setLevel(logging.ERROR) - xml = dicttoxml.dicttoxml(_dict, - cdata=['word', 'description'], - custom_root=root, - item_func=item_name_func, - xml_declaration=False, - encoding='utf-8', - attr_type=False).decode('utf-8') + xml = dict_to_xml(_dict, root_name=root, item_func=item_name_func) pretty_xml = parseString(xml).toprettyxml() if pretty_xml.startswith(' str: + """ + 将 dict 或 list 转换为 XML 字符串。 + + :param data: 要转换的 dict 或 list + :param root_name: XML 根元素名称 + :param item_func: 列表项元素名的函数,接收父元素名,返回子元素名 + :return: XML 字符串 + """ + root = ET.Element(root_name) + + if isinstance(data, dict): + for key, value in data.items(): + _add_element(root, key, value, item_func) + elif isinstance(data, list): + item_name = item_func(root_name) if item_func else 'item' + for item in data: + _add_element(root, item_name, item, item_func) + else: + root.text = str(data) + + return ET.tostring(root, encoding='unicode', xml_declaration=False) diff --git a/backend/pyproject.toml b/backend/pyproject.toml index b9ebd7d3..8882d5b5 100644 --- a/backend/pyproject.toml +++ b/backend/pyproject.toml @@ -47,7 +47,6 @@ dependencies = [ "python-calamine>=0.4.0", "xlrd>=2.0.2", "clickhouse-sqlalchemy>=0.3.2", - "dicttoxml>=1.7.16", "dmpython==2.5.22; platform_system != 'Darwin'", "redshift-connector>=2.1.8", "elasticsearch[requests] (>=7.10,<8.0)",