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

使用PHP将XML转换为可读CSV的实现难题

解析XML生成目标CSV的解决方案

原始XML数据

<?xml version="1.0" encoding="utf-8"?>
<!-- Generated by Oracle Reports version 12.2.1.4.0 -->
<REAL_ESTATE_OVERVIEW>
    <NAME>Mike Wazovski</NAME>
    <DATETIME>2022-09-23T16:30:45</DATETIME>
    <ESTATES>
        <ESTATE>
            <NAME>Son's house</NAME>
            <ROOMS>
                <ROOM>
                    <ID>MH_R_01</ID>
                    <AREA>66</AREA>
                </ROOM>
                <ROOM>
                    <ID>MH_R_02</ID>
                    <AREA>86</AREA>
                    <BEDS>2</BEDS>
                </ROOM>
            </ROOMS>
        </ESTATE>
        <ESTATE>
            <NAME>Wife's house</NAME>
            <ROOMS>
                <ROOM>
                    <ID>PH_R_01</ID>
                    <AREA>75</AREA>
                    <BEDS>2</BEDS>
                </ROOM>
                <ROOM>
                    <ID>PH_R_02</ID>
                    <AREA>77</AREA>
                </ROOM>
            </ROOMS>
        </ESTATE>
    </ESTATES>
</REAL_ESTATE_OVERVIEW>

期望生成的CSV结构

NAMEDATETIMEESTATE_NAMEROOM_IDROOM_AREAROOM_BEDS
Mike Wazovski2022-09-23T16:30:45Son's houseMH_R_0166
Mike Wazovski2022-09-23T16:30:45Son's houseMH_R_02862
Mike Wazovski2022-09-23T16:30:45Wife's housePH_R_01752
Mike Wazovski2022-09-23T16:30:45Wife's housePH_R_0277

原代码问题分析

你原来的递归逻辑将所有节点平铺为一维数组,没有处理XML中多重复嵌套结构(多个ESTATE、多个ROOM),无法生成对应多行的CSV数据,导致表头和行数据无法匹配目标格式。

修正后的PHP代码

$xmlStr = <<<XML
<?xml version="1.0" encoding="utf-8"?>
<!-- Generated by Oracle Reports version 12.2.1.4.0 -->
<REAL_ESTATE_OVERVIEW>
    <NAME>Mike Wazovski</NAME>
    <DATETIME>2022-09-23T16:30:45</DATETIME>
    <ESTATES>
        <ESTATE>
            <NAME>Son's house</NAME>
            <ROOMS>
                <ROOM>
                    <ID>MH_R_01</ID>
                    <AREA>66</AREA>
                </ROOM>
                <ROOM>
                    <ID>MH_R_02</ID>
                    <AREA>86</AREA>
                    <BEDS>2</BEDS>
                </ROOM>
            </ROOMS>
        </ESTATE>
        <ESTATE>
            <NAME>Wife's house</NAME>
            <ROOMS>
                <ROOM>
                    <ID>PH_R_01</ID>
                    <AREA>75</AREA>
                    <BEDS>2</BEDS>
                </ROOM>
                <ROOM>
                    <ID>PH_R_02</ID>
                    <AREA>77</AREA>
                </ROOM>
            </ROOMS>
        </ESTATE>
    </ESTATES>
</REAL_ESTATE_OVERVIEW>
XML;

$xml = simplexml_load_string($xmlStr);

// 初始化表头和数据行
$headers = ['NAME', 'DATETIME', 'ESTATE_NAME', 'ROOM_ID', 'ROOM_AREA', 'ROOM_BEDS'];
$rows = [];

// 获取顶层固定字段
$topName = (string)$xml->NAME;
$topDatetime = (string)$xml->DATETIME;

// 遍历每个房产
foreach ($xml->ESTATES->ESTATE as $estate) {
    $estateName = (string)$estate->NAME;
    // 遍历每个房间
    foreach ($estate->ROOMS->ROOM as $room) {
        $row = [
            $topName,
            $topDatetime,
            $estateName,
            (string)$room->ID,
            (string)$room->AREA,
            (string)$room->BEDS // 不存在时自动为空字符串
        ];
        $rows[] = $row;
    }
}

// 输出表头和数据(或写入CSV文件)
echo "<pre>";
print_r($headers);
echo "</pre>";

echo "<pre>";
print_r($rows);
echo "</pre>";

// 写入CSV文件示例
$fp = fopen('real_estate.csv', 'w');
fputcsv($fp, $headers);
foreach ($rows as $row) {
    fputcsv($fp, $row);
}
fclose($fp);

代码逻辑说明

  1. 固定表头定义:直接根据目标CSV结构定义表头,避免递归带来的冗余字段
  2. 层级遍历:
    • 先提取XML顶层的NAME和DATETIME,作为每行的固定值
    • 遍历每个ESTATE节点,获取房产名称
    • 遍历每个ESTATE下的ROOM节点,提取房间的ID、面积、床位数
  3. 行数据组装:将每层字段组合为一行,不存在的字段(如部分房间的BEDS)自动转为空字符串
  4. CSV输出:可直接打印数组查看结果,或通过fputcsv写入CSV文件

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 04:45:34