PHP CSV转XML脚本添加根元素属性崩溃及空文件问题求助
问题排查与修正
核心问题分析
1. 根元素<Station>添加属性崩溃
- 未明确属性值的合法来源,直接添加属性会因值未定义或非法触发报错
- XMLWriter操作顺序无误,但缺少对属性值的有效性校验
2. data-481.csv生成空XML
- 当前脚本仅在
trim($no) !== ''时生成<rec>元素,若该CSV中no字段全为空则无输出 - 可能存在CSV分隔符不匹配(比如实际是逗号而非分号),导致
fgetcsv无法正确解析数据,触发count($data) >=4的跳过逻辑
修正后的脚本
ini_set('display_errors', '1'); ini_set('display_startup_errors', '1'); error_reporting(E_ALL); // 配置每个CSV对应的Station属性,可根据实际需求扩展 $stationConfig = [ 'data-203.csv' => ['id' => '203', 'location' => 'Location A', 'geocode' => 'GC-203'], 'data-206.csv' => ['id' => '206', 'location' => 'Location B', 'geocode' => 'GC-206'], 'data-481.csv' => ['id' => '481', 'location' => 'Location C', 'geocode' => 'GC-481'], // 添加更多CSV对应的配置 ]; // List of CSV files $csvFiles = [ 'data-203.csv', 'data-206.csv', 'data-481.csv' ]; // Loop through each CSV file foreach ($csvFiles as $csvFile) { $csvFilePath = __DIR__ . '/' . $csvFile; // 检查文件是否存在且可读 if (!file_exists($csvFilePath) || !is_readable($csvFilePath)) { echo "Error: Cannot access file $csvFile\n"; continue; } // Open the CSV file if (($handle = fopen($csvFilePath, 'r')) !== false) { // Create an XMLWriter instance $xmlWriter = new XMLWriter(); $xmlWriter->openURI(csvFileToXmlFile($csvFile)); $xmlWriter->startDocument('1.0', 'UTF-8'); $xmlWriter->startElement('Station'); // 为根元素添加属性,先校验配置是否存在 if (isset($stationConfig[$csvFile])) { $config = $stationConfig[$csvFile]; // 写入属性前校验值是否非空 if (!empty($config['id'])) $xmlWriter->writeAttribute('id', $config['id']); if (!empty($config['location'])) $xmlWriter->writeAttribute('location', $config['location']); if (!empty($config['geocode'])) $xmlWriter->writeAttribute('geocode', $config['geocode']); } // Read the CSV file line by line $lineCount = 0; while (($data = fgetcsv($handle, 10000, ';')) !== false) { $lineCount++; // Skip empty lines if (count($data) === 0 || (count($data) ===1 && trim($data[0]) === '')) { continue; } // 允许至少timestamp存在时生成记录,放宽判断条件 if (count($data) >=1 && trim($data[0]) !== '') { // Extract the necessary data,不存在的字段设为空字符串 $timestamp = trim($data[0] ?? ''); $nox = trim($data[1] ?? ''); $no2 = trim($data[2] ?? ''); $no = trim($data[3] ?? ''); // Start XML record element $xmlWriter->startElement('rec'); $xmlWriter->writeAttribute('ts', $timestamp); if ($nox !== '') $xmlWriter->writeAttribute('nox', $nox); if ($no2 !== '') $xmlWriter->writeAttribute('no2', $no2); if ($no !== '') $xmlWriter->writeAttribute('no', $no); // End XML record element $xmlWriter->endElement(); } } // Close XML elements and file $xmlWriter->endElement(); $xmlWriter->endDocument(); $xmlWriter->flush(); fclose($handle); // 输出生成结果,包含行数统计 $xmlFile = csvFileToXmlFile($csvFile); echo "XML file generated successfully: $xmlFile (processed $lineCount lines)\n"; } else { echo "Error: Cannot open file $csvFile\n"; } } // Function to convert CSV file name to XML file name function csvFileToXmlFile($csvFile) { $fileParts = pathinfo($csvFile); $xmlFile = $fileParts['filename'] . '.xml'; return __DIR__ . '/' . $xmlFile; // 确保XML文件生成在同一目录 }
关键修正点
- 添加
stationConfig数组,明确每个CSV对应的Station属性,避免属性值未定义导致崩溃 - 增加文件存在性和可读性检查,提前捕获错误
- 放宽
<rec>元素生成条件:只要timestamp非空就生成,避免因单一字段为空导致无输出 - 对CSV字段做默认值处理,避免索引不存在报错
- 输出处理行数,方便排查空文件问题
- 修正
csvFileToXmlFile函数,确保XML文件生成在脚本所在目录
内容的提问来源于stack exchange,提问作者grimx
相关产品推荐
相关产品推荐

