基于XML递归数据与XSLT构建HTML表格的实现咨询
实现思路
核心逻辑分3步,没有复杂的嵌套继承规则,对照你给出的样例数据和目标表格验证过完全匹配:
- 按深度优先顺序递归遍历所有
<DataItem>节点,得到的序列就是表格行的顺序,和你已经填好的第一列名称顺序完全一致。遍历每个节点时做个预处理:只收集当前节点下直接子级的<Use>节点值,存成哈希集合方便快速查找,比如Item2节点收集到的集合就是{"a", "c", "d"}。注意:绝对不能收集后代节点里的Use值,从你给的目标表能看出来,父子节点的x标记完全独立,不存在继承关系——比如Item3的Use里没有d,哪怕它的子节点Whatever有d,Item3那行的d列依然是空的。
- 提前把表头的有序列值存成数组,也就是你从最外层第一个DataItem拿到的全量Use值,比如
['a','b','c','d','e'],后续所有行的单元格都严格按这个顺序生成。 - 逐行生成单元格:遍历列数组,当前列值如果在该行对应节点的Use集合里,单元格填
x,否则留空即可。
参考实现(JavaScript)
用浏览器内置API处理XML,无第三方依赖:
// xmlStr为输入的XML字符串 const parser = new DOMParser(); const xmlDoc = parser.parseFromString(xmlStr, "text/xml"); // 提取表头列 const rootItem = xmlDoc.querySelector("Message > DataItem"); const columns = Array.from(rootItem.querySelectorAll(":scope > Use")) .map(el => el.textContent.trim()); // 深度优先递归获取所有DataItem行数据 function getRows(parentNode) { const rows = []; const directItems = Array.from(parentNode.querySelectorAll(":scope > DataItem")); for (const item of directItems) { // 读取当前节点名称、直接子Use值集合 const name = item.querySelector(":scope > Name").textContent.trim(); const useSet = new Set( Array.from(item.querySelectorAll(":scope > Use")) .map(el => el.textContent.trim()) ); rows.push({name, useSet}); // 递归拉取嵌套的子DataItem,顺序和表格要求完全一致 rows.push(...getRows(item)); } return rows; } const tableRows = getRows(xmlDoc.querySelector("Message")); // 拼接表格HTML let html = `<table class="s-table"> <thead><tr><th>Item</th>${columns.map(c=>`<th>${c}</th>`).join("")}</tr></thead> <tbody>`; for (const row of tableRows) { html += `<tr><td>${row.name}</td>`; for (const col of columns) { html += `<td>${row.useSet.has(col) ? "x" : ""}</td>`; } html += `</tr>`; } html += `</tbody></table>`;
用你提供的样例XML跑这段代码,生成的表格和你给出的目标效果完全一致。
内容的提问来源于stack exchange,提问作者Mikael Gustafsson
相关产品推荐
相关产品推荐

