XML文件上传解析为HTML表格失败,请求技术协助
问题修复:XML文件上传解析转HTML表格
问题根源
- 扩展名判断逻辑漏洞:原代码通过
explode(".", 文件名)获取扩展名,无法处理含多个点的文件名(如data.v1.xml)或大小写扩展名(如.XML),导致误判。 - XML解析逻辑错误:照搬CSV的逐行读取逻辑,XML是树形结构,不能用
fopen配合循环调用simplexml_load_file的方式读取,这种方式完全不符合XML的解析规则。
修复后的代码
1. 修正后的upload.php
<?php //upload.php session_start(); $error = ''; $html = ''; if(isset($_FILES['file']) && $_FILES['file']['name'] != '') { // 用pathinfo可靠获取扩展名,并转小写避免大小写问题 $extension = strtolower(pathinfo($_FILES['file']['name'], PATHINFO_EXTENSION)); if($extension == 'xml') { // 直接加载XML文件,无需fopen $xml = simplexml_load_file($_FILES['file']['tmp_name']); if(!$xml){ $error = 'XML文件解析失败,请检查文件格式'; }else{ // 假设XML根节点下的子节点是<item>,根据实际XML结构调整 $items = $xml->children(); if(empty($items)){ $error = 'XML文件中未找到数据节点'; }else{ // 获取第一个item的字段作为表头 $first_item = $items[0]; $fields = array(); foreach($first_item->children() as $child){ $fields[] = $child->getName(); } // 构建HTML表格表头 $html .= '<table class="table table-bordered"><tr>'; foreach($fields as $index => $field){ $html .= ' <th> <select name="set_column_data" class="form-control set_column_data" data-column_number="'.$index.'"> <option value="">Set Count Data</option> <option value="sku">sku</option> <option value="category_id">category_id</option> <option value="price">price</option> <option value="discount_rate">discount_rate</option> <option value="vat_rate">vat_rate</option> <option value="stock">stock</option> <option value="external_link">external_link</option> </select> </th> '; } $html .= '</tr>'; // 构建表格内容,最多显示5行 $limit = 0; $temp_data = array(); foreach($items as $item){ $limit++; if($limit < 6){ $html .= '<tr>'; foreach($item->children() as $child){ $html .= '<td>'.$child.'</td>'; } $html .= '</tr>'; } // 保存XML数据到临时数组(转为数组方便后续处理) $temp_data[] = (array)$item; } $_SESSION['file_data'] = $temp_data; $html .= ' </table> <br /> <div align="right"> <button type="button" name="import" id="import" class="btn btn-success" disabled>Import</button> </div> <br /> '; } } } else { $error = 'Only <b>.xml</b> file allowed'; } } else { $error = 'Please Select XML File'; } $output = array( 'error' => $error, 'output' => $html ); echo json_encode($output); ?>
2. 关键修复点说明
- 扩展名判断:使用
pathinfo()函数获取扩展名,配合strtolower()统一转为小写,彻底解决文件名含多点、扩展名大小写的问题。 - XML解析:
- 直接用
simplexml_load_file()加载临时文件路径,无需手动打开文件。 - 遍历XML的树形节点,先获取第一个数据节点的字段作为表头,再循环所有数据节点生成表格行。
- 添加了解析失败的错误判断,避免空数据导致的页面异常。
- 直接用
- 数据存储:将XML节点转为数组后存入Session,方便后续导入操作使用。
3. 适配XML结构说明
如果你的XML结构不是<items><item>...</item></items>的形式,需要调整代码中$items = $xml->children();这一行,改为对应你的数据节点名称,比如如果根节点是<products>,子节点是<product>,则改为$items = $xml->product;。
前端AJAX脚本(无需修改)
原AJAX提交逻辑正常,保持即可:
<script src="https://code.jquery.com/jquery.js"></script> <script> $(document).ready(function(){ $('#upload_form').on('submit', function(event){ event.preventDefault(); $.ajax({ url:"upload.php", method:"POST", data:new FormData(this), dataType:'json', contentType:false, cache:false, processData:false, success:function(data) { if(data.error != '') { $('#message').html('<div class="alert alert-danger">'+data.error+'</div>'); } else { $('#process_area').html(data.output); $('#upload_area').css('display', 'none'); } } }); }); }); </script>
内容的提问来源于stack exchange,提问作者Marcin
相关产品推荐
相关产品推荐

