refactor: replace dicttoxml with stdlib implementation to avoid GPL license risk

This commit is contained in:
ulleo
2026-07-24 18:09:00 +08:00
committed by ulleo
parent 9656efad06
commit 9726db544d
4 changed files with 53 additions and 21 deletions
@@ -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.system.models.system_model import AssistantModel
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('<?xml'):
+2 -10
View File
@@ -1,10 +1,8 @@
import datetime
import logging
import traceback
from typing import List, Optional, Any
from xml.dom.minidom import parseString
import dicttoxml
from sqlalchemy import and_, or_, select, func, delete, update, union, text, BigInteger
from sqlalchemy.orm import aliased
@@ -15,6 +13,7 @@ from apps.template.generate_chart.generator import get_base_terminology_template
from apps.terminology.models.terminology_model import Terminology, TerminologyInfo, TerminologyInfoResult
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_terminology_embeddings
@@ -949,14 +948,7 @@ def get_example():
def to_xml_string(_dict: list[dict] | dict, root: str = 'terminologies') -> 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('<?xml'):
+49
View File
@@ -0,0 +1,49 @@
"""
将 dict/list 转换为 XML 字符串的工具函数,用于替代 dicttoxml 库(GPL 许可证风险)。
仅依赖 Python 标准库。
"""
import xml.etree.ElementTree as ET
def _add_element(parent: ET.Element, key: str, value, item_func=None):
"""递归地将值添加为 XML 子元素。"""
elem = ET.SubElement(parent, key)
if isinstance(value, dict):
for k, v in value.items():
_add_element(elem, k, v, item_func)
elif isinstance(value, list):
item_name = item_func(key) if item_func else 'item'
for item in value:
_add_element(elem, item_name, item, item_func)
elif isinstance(value, bool):
elem.text = str(value).lower()
elif value is None:
elem.text = ''
else:
elem.text = str(value)
def dict_to_xml(data: dict | list, root_name: str = 'root', item_func=None) -> 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)
-1
View File
@@ -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)",