Node.js遍历含数组对象的树结构清除null/undefined/空值方法
UBL嵌套JSON空值级联清理实现方案
核心处理规则
- 非法值判定范围:仅移除
null、undefined、空字符串'',数值0、布尔值false属于合法业务值予以保留 - 采用后序深度优先遍历逻辑:优先处理最深层子节点,再向上判断父节点是否因子节点全被清空需要移除,实现级联删除
- 全程采用原地修改逻辑,不全量重建对象/数组,保证原有属性排列顺序完全不变
- 自动适配任意层级的数组、对象嵌套结构,无需提前配置节点路径,可直接适配数百个节点的批量处理场景
可直接运行的实现代码
/** * 嵌套结构空值清理函数 * @param {any} node 待处理节点 * @returns {any} 处理后节点,返回null表示当前节点为空需要上层移除 */ function cleanEmptyNodes(node) { // 基础非法值直接返回null标记移除 if (node === null || node === undefined || node === '') { return null; } // 非容器类型(数字、布尔、日期等合法基础值)直接返回 if (typeof node !== 'object') { return node; } // 处理数组结构 if (Array.isArray(node)) { // 倒序遍历避免删除元素时索引偏移漏处理 for (let i = node.length - 1; i >= 0; i--) { const cleanedItem = cleanEmptyNodes(node[i]); if (cleanedItem === null) { node.splice(i, 1); } else { node[i] = cleanedItem; } } // 清理后为空的数组返回null,触发上层级联删除 return node.length === 0 ? null : node; } // 处理普通对象结构 for (const key of Object.keys(node)) { const cleanedValue = cleanEmptyNodes(node[key]); if (cleanedValue === null) { delete node[key]; } else { node[key] = cleanedValue; } } // 清理后无任何属性的空对象返回null,触发上层级联删除 return Object.keys(node).length === 0 ? null : node; } // 调用方式:直接传入xml2js转换得到的UBL Invoice根节点即可 // 注意:函数会原地修改原对象,若需保留原始数据请先传入深拷贝副本 // const cleanedResult = cleanEmptyNodes(structuredClone(rawUblInvoiceData));
适配说明
- 兼容xml2js转换输出的特殊结构:包括存储属性的
$字段、存储文本值的_字段,无需额外编写适配规则,空属性对象、空文本值会被自动识别清理 - 处理后对象的键顺序与xml2js原始输出完全一致,不会出现键重排问题
- 可通过修改最开始的非法值判断逻辑,扩展需要移除的空值类型(比如空的纯空格字符串)
内容的提问来源于stack exchange,提问作者Anders
相关产品推荐
相关产品推荐

