You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将包含多层嵌套子节点的XML文件完整导入MySQL对应数据表

问题原因

你当前的写法只能拿到单个节点的原因有两个:

  • LOAD DATA LOCAL INFILE 按<product>到</product>拆分每行数据,一个product只会生成一行待插入记录,就算一个product下有多个area,也只会执行一次插入操作
  • ExtractValue 匹配到多个节点时,默认只返回第一个匹配到的节点内容
解决方案1:使用MySQL存储过程批量遍历节点

首先第一步先修正XML文件:在所有内容的最外层加<root>和</root>标签,否则MySQL的XML解析器会因为多根节点报错。
如果执行时提示本地文件读取权限问题,先执行语句开启权限:SET GLOBAL local_infile = 1;
之后执行如下存储过程代码即可完成导入:

DELIMITER //
CREATE PROCEDURE import_areas()
BEGIN
    DECLARE i INT DEFAULT 1;
    DECLARE total_area INT;
    -- 读取整个XML文件内容到临时表
    CREATE TEMPORARY TABLE IF NOT EXISTS xml_raw (content LONGTEXT);
    LOAD DATA LOCAL INFILE '/var/lib/mysql/allprintdatafile_esp.xml' 
    INTO TABLE xml_raw 
    CHARACTER SET utf8;
    SET @xml = (SELECT content FROM xml_raw);
    -- 统计总共有多少个area节点
    SET total_area = ExtractValue(@xml, 'count(//area)');
    -- 循环插入每个area对应的数据
    WHILE i <= total_area DO
        INSERT INTO areas (id_area, id_print_job, id_product, areaname)
        VALUES (
            ExtractValue(@xml, CONCAT('//area[',i,']/areacode')),
            ExtractValue(@xml, CONCAT('//area[',i,']/../../teccode')),
            ExtractValue(@xml, CONCAT('//area[',i,']/../../../../ref')),
            TRIM(ExtractValue(@xml, CONCAT('//area[',i,']/areaname')))
        );
        SET i = i + 1;
    END WHILE;
    DROP TEMPORARY TABLE xml_raw;
END //
DELIMITER ;

-- 执行存储过程完成导入
CALL import_areas();

如果要导入product、printjob表,只需要调整遍历的节点和对应的XPath取值逻辑即可。

解决方案2:用脚本预处理后导入(更推荐,容错率更高)

如果熟悉Python等脚本语言,可以先解析XML提取所有需要的字段再批量插入数据库,不需要处理MySQL的XML语法兼容问题,示例逻辑如下:

import xml.etree.ElementTree as ET
import pymysql

# 解析XML文件
tree = ET.parse('allprintdatafile_esp.xml')
root = tree.getroot()
data_list = []

for product in root.findall('product'):
    product_ref = product.find('ref').text
    for printjob in product.find('printjobs').findall('printjob'):
        teccode = printjob.find('teccode').text
        for area in printjob.find('areas').findall('area'):
            areacode = area.find('areacode').text
            areaname = area.find('areaname').text.strip()
            data_list.append((areacode, teccode, product_ref, areaname))

# 批量插入数据库
conn = pymysql.connect(host='localhost', user='你的数据库账号', password='你的数据库密码', database='你的库名', charset='utf8')
cursor = conn.cursor()
cursor.executemany("INSERT INTO areas (id_area, id_print_job, id_product, areaname) VALUES (%s, %s, %s, %s)", data_list)
conn.commit()
conn.close()

注:你给出的预期结果中第三行的areaname属于手误,原XML对应第三个printjob的areaname为Esquina inferior derecha de la portada,上述两种方法都会自动匹配正确的内容。

内容的提问来源于stack exchange,提问作者rues_12

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.28 21:45:02