Skip to content

Commit 6042331

Browse files
committed
refactor: replace dicttoxml with stdlib implementation to avoid GPL license risk
1 parent 9656efa commit 6042331

4 files changed

Lines changed: 53 additions & 21 deletions

File tree

backend/apps/data_training/curd/data_training.py

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,8 @@
11
import datetime
2-
import logging
32
import traceback
43
from typing import List, Optional
54
from xml.dom.minidom import parseString
65

7-
import dicttoxml
86
from sqlalchemy import and_, select, func, delete, update, or_
97
from sqlalchemy import text
108

@@ -15,6 +13,7 @@
1513
from apps.template.generate_chart.generator import get_base_data_training_template
1614
from common.core.config import settings
1715
from common.core.deps import SessionDep, Trans
16+
from common.utils.dict_to_xml import dict_to_xml
1817
from common.utils.embedding_threads import run_save_data_training_embeddings
1918

2019

@@ -594,14 +593,7 @@ def select_training_by_question(session: SessionDep, question: str, oid: int, da
594593

595594
def to_xml_string(_dict: list[dict] | dict, root: str = 'sql-examples') -> str:
596595
item_name_func = lambda x: 'sql-example' if x == 'sql-examples' else 'item'
597-
dicttoxml.LOG.setLevel(logging.ERROR)
598-
xml = dicttoxml.dicttoxml(_dict,
599-
cdata=['question', 'suggestion-answer'],
600-
custom_root=root,
601-
item_func=item_name_func,
602-
xml_declaration=False,
603-
encoding='utf-8',
604-
attr_type=False).decode('utf-8')
596+
xml = dict_to_xml(_dict, root_name=root, item_func=item_name_func)
605597
pretty_xml = parseString(xml).toprettyxml()
606598

607599
if pretty_xml.startswith('<?xml'):

backend/apps/terminology/curd/terminology.py

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,8 @@
11
import datetime
2-
import logging
32
import traceback
43
from typing import List, Optional, Any
54
from xml.dom.minidom import parseString
65

7-
import dicttoxml
86
from sqlalchemy import and_, or_, select, func, delete, update, union, text, BigInteger
97
from sqlalchemy.orm import aliased
108

@@ -15,6 +13,7 @@
1513
from apps.terminology.models.terminology_model import Terminology, TerminologyInfo, TerminologyInfoResult
1614
from common.core.config import settings
1715
from common.core.deps import SessionDep, Trans
16+
from common.utils.dict_to_xml import dict_to_xml
1817
from common.utils.embedding_threads import run_save_terminology_embeddings
1918

2019

@@ -949,14 +948,7 @@ def get_example():
949948

950949
def to_xml_string(_dict: list[dict] | dict, root: str = 'terminologies') -> str:
951950
item_name_func = lambda x: 'terminology' if x == 'terminologies' else 'word' if x == 'words' else 'item'
952-
dicttoxml.LOG.setLevel(logging.ERROR)
953-
xml = dicttoxml.dicttoxml(_dict,
954-
cdata=['word', 'description'],
955-
custom_root=root,
956-
item_func=item_name_func,
957-
xml_declaration=False,
958-
encoding='utf-8',
959-
attr_type=False).decode('utf-8')
951+
xml = dict_to_xml(_dict, root_name=root, item_func=item_name_func)
960952
pretty_xml = parseString(xml).toprettyxml()
961953

962954
if pretty_xml.startswith('<?xml'):
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
"""
2+
将 dict/list 转换为 XML 字符串的工具函数,用于替代 dicttoxml 库(GPL 许可证风险)。
3+
仅依赖 Python 标准库。
4+
"""
5+
6+
import xml.etree.ElementTree as ET
7+
8+
9+
def _add_element(parent: ET.Element, key: str, value, item_func=None):
10+
"""递归地将值添加为 XML 子元素。"""
11+
elem = ET.SubElement(parent, key)
12+
13+
if isinstance(value, dict):
14+
for k, v in value.items():
15+
_add_element(elem, k, v, item_func)
16+
elif isinstance(value, list):
17+
item_name = item_func(key) if item_func else 'item'
18+
for item in value:
19+
_add_element(elem, item_name, item, item_func)
20+
elif isinstance(value, bool):
21+
elem.text = str(value).lower()
22+
elif value is None:
23+
elem.text = ''
24+
else:
25+
elem.text = str(value)
26+
27+
28+
def dict_to_xml(data: dict | list, root_name: str = 'root', item_func=None) -> str:
29+
"""
30+
将 dict 或 list 转换为 XML 字符串。
31+
32+
:param data: 要转换的 dict 或 list
33+
:param root_name: XML 根元素名称
34+
:param item_func: 列表项元素名的函数,接收父元素名,返回子元素名
35+
:return: XML 字符串
36+
"""
37+
root = ET.Element(root_name)
38+
39+
if isinstance(data, dict):
40+
for key, value in data.items():
41+
_add_element(root, key, value, item_func)
42+
elif isinstance(data, list):
43+
item_name = item_func(root_name) if item_func else 'item'
44+
for item in data:
45+
_add_element(root, item_name, item, item_func)
46+
else:
47+
root.text = str(data)
48+
49+
return ET.tostring(root, encoding='unicode', xml_declaration=False)

backend/pyproject.toml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,6 @@ dependencies = [
4747
"python-calamine>=0.4.0",
4848
"xlrd>=2.0.2",
4949
"clickhouse-sqlalchemy>=0.3.2",
50-
"dicttoxml>=1.7.16",
5150
"dmpython==2.5.22; platform_system != 'Darwin'",
5251
"redshift-connector>=2.1.8",
5352
"elasticsearch[requests] (>=7.10,<8.0)",

0 commit comments

Comments
 (0)