如何用JavaScript从JSON提取URL并构建部落小队层级结构
问题描述
我有如下JSON测试报告数据:
[ { "line": 1, "elements": [ { "start_timestamp": "2022-10-17T20:07:41.706Z", "steps": [ { "result": { "duration": 12216552000, "status": "passed" }, "line": 5, "name": "m0e", "match": { "location": "seleniumgluecode.book.user_is_on_homepagee()" }, "keyword": "Given " }, { "result": { "duration": 2074982200, "status": "passed" }, "line": 6, "name": "m1e1", "match": { "location": "seleniumgluecode.book.user_enters_Usernamee()" }, "keyword": "When " } ], "tags": [{ "name": "@Smokee" }] }, { "start_timestamp": "2022-10-17T20:08:12.284Z", "steps": [ { "result": { "duration": 12090584100, "status": "passed" }, "line": 12, "name": "m0e2", "match": { "location": "seleniumgluecode.book2.user_is_on_homepageee()" }, "keyword": "Given " } ], "tags": [{ "name": "@Smokee" }] } ], "name": "Login Featuree", "description": " Verify if user is able to Login in to the sitee", "id": "login-featuree", "keyword": "Feature", "uri": "file:src/test/java/features/tribe1/squad1/kitab.feature", "tags": [] }, { "line": 1, "elements": [ { "start_timestamp": "2022-10-17T20:08:34.480Z", "steps": [ { "result": { "duration": 11366098500, "status": "passed" }, "line": 5, "name": "m0e", "match": { "location": "seleniumgluecode.book.user_is_on_homepagee()" }, "keyword": "Given " } ], "tags": [{ "name": "@Smokee" }] } ], "name": "Login Featureefghfgh", "description": " Verify if user is able to Login in to the sitee", "id": "login-featureefghfgh", "keyword": "Feature", "uri": "file:src/test/java/features/tribe1/squad2/kitab2.feature", "tags": [] }, { "line": 19, "elements": [ { "start_timestamp": "2022-10-17T20:09:40.836Z", "steps": [ { "result": { "duration": 12761711100, "status": "passed" }, "line": 23, "name": "m0e", "match": { "location": "seleniumgluecode.book.user_is_on_homepagee()" }, "keyword": "Given " } ], "tags": [{ "name": "@Smokee" }] } ], "name": "X Feature", "description": " Verify if user is able to Login in to the sitee", "id": "login-featuree", "keyword": "Feature", "uri": "file:src/test/java/features/tribe2/test.feature", "tags": [] } ]
我用下面的JS代码提取URI地址:
document.addEventListener("DOMContentLoaded", () => { var i = report.length; var array = []; for(x = 0; x < i; x++){ array.push(report[x].uri.split("/")); } console.log(array2); // 此处笔误,应为array });
得到的结果是:
[ ['file:src', 'test', 'java', 'features', 'tribe1', 'squad1', 'kitab.feature'], ['file:src', 'test', 'java', 'features', 'tribe1', 'squad2', 'kitab2.feature'], ['file:src', 'test', 'java', 'features', 'tribe2', 'test.feature'] ]
我需要移除file:src、test、java、features这四个前缀,得到:
[ ['tribe1', 'squad1', 'kitab.feature'], ['tribe1', 'squad2', 'kitab2.feature'], ['tribe2', 'test.feature'] ]
最终要根据这些路径段构建层级结构:如果.feature文件前有两个元素,第一个是部落(tribe)、第二个是小队(squad);如果只有一个元素,那就是部落直接对应feature。结构示例如下:
[tribe1 squad1 elem 1 2 name: Login Featuree url: file:src/test/java/features/tribe1/squad1/kitab.feature squad2 elem 1 name: Login Featureefghfgh url: file:src/test/java/features/tribe1/squad2/kitab2.feature tribe2 elem 1 name: X Feature url: file:src/test/java/features/tribe2/test.feature ]
解决方案
1. 移除URI前缀,提取目标路径段
直接用数组的slice方法去掉前4个元素即可,修正后的提取代码如下:
document.addEventListener("DOMContentLoaded", () => { const pathSegmentsArray = report.map(item => { // 分割URI后,去掉前4个前缀元素 return item.uri.split("/").slice(4); }); console.log(pathSegmentsArray); // 后续层级构建逻辑写在这里 });
运行后就能得到你想要的路径段数组。
2. 构建部落-小队的层级结构
用一个对象来存储最终的层级数据,遍历每个测试报告项,解析路径段中的部落、小队、feature信息,同时把对应的name、uri、elements(步骤数)关联进去:
document.addEventListener("DOMContentLoaded", () => { const hierarchy = {}; report.forEach(item => { const pathSegments = item.uri.split("/").slice(4); let tribe, squad, featureName; // 解析路径段 if (pathSegments.length === 3) { // 格式:[tribe, squad, feature] tribe = pathSegments[0]; squad = pathSegments[1]; featureName = pathSegments[2]; } else if (pathSegments.length === 2) { // 格式:[tribe, feature] tribe = pathSegments[0]; squad = null; featureName = pathSegments[1]; } // 初始化部落节点 if (!hierarchy[tribe]) { hierarchy[tribe] = { squads: {}, features: [] }; } // 收集feature的信息:元素数量(elements的长度)、name、uri const featureInfo = { elemCount: item.elements.length, name: item.name, url: item.uri }; // 区分有小队和无小队的情况 if (squad) { // 初始化小队节点 if (!hierarchy[tribe].squads[squad]) { hierarchy[tribe].squads[squad] = { features: [] }; } hierarchy[tribe].squads[squad].features.push(featureInfo); } else { hierarchy[tribe].features.push(featureInfo); } }); // 格式化输出成你要的结构 const formattedOutput = Object.entries(hierarchy).map(([tribe, data]) => { let output = `${tribe}\n`; // 处理小队 if (Object.keys(data.squads).length > 0) { Object.entries(data.squads).forEach(([squad, squadData]) => { output += ` ${squad}\n`; squadData.features.forEach(feature => { output += ` elem\n`; // 生成elem的序号(1到elemCount) for (let i = 1; i <= feature.elemCount; i++) { output += ` ${i}\n`; } output += ` name: ${feature.name}\n`; output += ` url: ${feature.url}\n`; }); }); } // 处理无小队的feature if (data.features.length > 0) { data.features.forEach(feature => { output += ` elem\n`; for (let i = 1; i <= feature.elemCount; i++) { output += ` ${i}\n`; } output += ` name: ${feature.name}\n`; output += ` url: ${feature.url}\n`; }); } return output; }).join(""); console.log(formattedOutput); });
运行结果
上述代码运行后,会输出你想要的层级结构:
tribe1 squad1 elem 1 2 name: Login Featuree url: file:src/test/java/features/tribe1/squad1/kitab.feature squad2 elem 1 name: Login Featureefghfgh url: file:src/test/java/features/tribe1/squad2/kitab2.feature tribe2 elem 1 name: X Feature url: file:src/test/java/features/tribe2/test.feature
内容的提问来源于stack exchange,提问作者CRYPTO
相关产品推荐
相关产品推荐

