多XML声明头致解析失败,求PHP处理及Bootstrap表格展示方案
解决多XML声明的解析问题并输出到Bootstrap表格
遇到这种包含多个XML声明的无效文件,我们可以分三步解决:预处理清理XML、解析提取数据、渲染Bootstrap表格。下面是完整的解决方案:
1. 预处理XML,移除多余的XML声明
一个合法的XML文档只能有一个<?xml?>声明,所以第一步要把文件中重复的声明去掉,只保留第一个。这里用字符串处理结合正则的方式来实现,比单纯正则更稳妥:
<?php // 读取原始XML文件 $str = file_get_contents('log.xml'); // 清理多余的XML声明:保留第一个,删除后续所有 $firstXmlDeclStart = strpos($str, '<?xml'); if ($firstXmlDeclStart !== false) { $firstXmlDeclEnd = strpos($str, '?>', $firstXmlDeclStart) + 2; // 截取第一个声明部分 $cleanedXml = substr($str, 0, $firstXmlDeclEnd); // 处理剩余部分,删除所有XML声明 $remainingContent = substr($str, $firstXmlDeclEnd); $cleanedXml .= preg_replace('/<\?xml.*?\?>/s', '', $remainingContent); } else { // 如果没有XML声明,直接用原始内容 $cleanedXml = $str; } ?>
2. 解析XML并安全提取数据
处理后的XML可以正常用SimpleXML解析了,同时我们要做容错处理(避免某些节点缺失导致报错),并把数据存入数组方便后续渲染:
<?php // 继续上面的代码 $xml = simplexml_load_string($cleanedXml); $extractedData = []; $counter = 0; // 确保节点存在再遍历,避免报错 if ($xml && isset($xml->uR->TS->Location)) { foreach ($xml->uR->TS->Location as $loc) { $counter++; // 用null合并运算符处理可能缺失的节点/属性 $extractedData[] = [ 'id' => $counter, 'tpl' => (string)($loc->attributes()['tpl'] ?? ''), 'arrival_time' => (string)($loc->arr->attributes()['at'] ?? ''), 'departure_time' => (string)($loc->dep->attributes()['et'] ?? ''), 'platform' => (string)($loc->plat ?? '') ]; } } ?>
3. 渲染成Bootstrap表格
最后把提取到的数据渲染成Bootstrap样式的表格,先引入Bootstrap CSS,再循环生成表格行:
<?php // 继续上面的代码 // 引入Bootstrap CSS(如果你的项目已经引入过可以省略) echo '<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">'; // 生成表格 echo '<div class="container mt-4">'; echo '<h3>XML数据展示</h3>'; echo '<table class="table table-striped table-hover table-bordered">'; // 表头 echo '<thead class="table-dark">'; echo '<tr>'; echo '<th>序号</th>'; echo '<th>TPL</th>'; echo '<th>到达时间</th>'; echo '<th>出发时间</th>'; echo '<th>站台</th>'; echo '</tr>'; echo '</thead>'; // 表体 echo '<tbody>'; foreach ($extractedData as $row) { echo '<tr>'; echo "<td>{$row['id']}</td>"; echo "<td>{$row['tpl']}</td>"; echo "<td>{$row['arrival_time']}</td>"; echo "<td>{$row['departure_time']}</td>"; echo "<td>{$row['platform']}</td>"; echo '</tr>'; } echo '</tbody>'; echo '</table>'; echo '</div>'; ?>
额外注意事项
- 如果你的XML文件编码和当前PHP环境编码不一致,可能会出现乱码,可以在
file_get_contents后用mb_convert_encoding统一编码。 - 如果XML结构有嵌套更深或者更复杂的情况,可以根据实际调整节点遍历的逻辑。
内容的提问来源于stack exchange,提问作者Haitham
相关产品推荐
相关产品推荐

