Node.js fast-xml-parser库的使用

12次阅读

fast-xml-parser 解析失败主因是输入非法XML或含bom/注释/DOCTYPE等默认不支持内容;需按需配置ignoredeclaration、ignoreComment等选项,并注意parseTagValue/parseAttributeValue对结构的影响。

Node.js fast-xml-parser库的使用

fast-xml-parser 解析 XML 字符串失败,返回空对象或报错

常见原因是输入不是合法 XML,或含 BOM、注释、DOCTYPE 等 fast-xml-parser 默认不处理的内容。它默认只解析标准格式的 XML,且不支持 DTD 和 CDATA(除非显式开启)。

  • 检查原始字符串是否以 开头,或至少以 类标签起始;用 console.log(jsON.stringify(xmlStr.slice(0, 50))) 看前 50 字符,确认无隐藏 BOM(如 uFEFF
  • 若 XML 含注释(),需启用 ignoreDeclaration: falseignoreAttributes: false,并设 ignoreComment: false
  • 若含 /code>,必须设 ignoreDeclaration: true(否则直接抛 Invalid XML: DOCTYPE is not supported
const { parse } = require('fast-xml-parser'); const options = {   ignoreAttributes: false,   ignoreDeclaration: true,   ignoreComment: false,   ignoreCdata: false,   parseTagValue: true,   parseAttributeValue: true }; const result = parse(xmlString, options); // 不再因注释/DOCTYPE 崩溃

如何保留 XML 中的属性和文本混合结构

fast-xml-parser 默认把属性转成带 @_ 前缀的键,文本内容则放在 #text 键下。但若没开 parseTagValueparseAttributeValue,所有值都会是字符串,无法区分属性与子节点文本。

  • parseTagValue: true 才会把纯文本子节点(如 Alice)的值提取为字符串,否则整个 节点会是空对象
  • parseAttributeValue: true 才能把 中的 id 解析为 { "@_id": "123" },否则属性被完全忽略
  • 若需扁平化(如把 @_id 直接变 id),得后处理:遍历对象,用 Object.keys().filter(k => k.startsWith('@_')) 提取并重命名

解析大文件时内存溢出或卡死

fast-xml-parser 是纯内存解析器,不支持流式(streaming)或 SAX 模式。XML 超过几 MB 就可能触发 node.js 内存限制(默认 1.4GB),尤其当启用了 ignoreAttributes: false 生成大量嵌套对象时。

  • process.memoryUsage().heapUsed / 1024 / 1024 监控解析前后内存变化
  • 对 >2MB 的 XML,优先考虑改用 saxlibxmljs 这类流式库;若必须用 fast-xml-parser,先用 fs.readFileSync 读取后做简单校验(如统计 出现次数),避免无效大文件进解析流程
  • 禁用不必要的选项:如确定无属性,设 ignoreAttributes: true 可减少 30%+ 对象创建量

json 再序列化回 XML 时格式错乱或丢失信息

fast-xml-parserrender 方法不保证 round-trip 精确还原:它不会保留原始缩进、换行、属性顺序,且对 #text@_ 键的处理有隐含规则。

  • 若源 XML 有同名兄弟节点(如多个 ),解析后是数组;但若只有一个,解析结果是单个对象——render 时不会自动补成数组,导致结构不一致
  • 解决办法:解析后统一用 Array.isArray(obj.item) ? obj.item : [obj.item] 规范化,再传给 render
  • render 不处理 undefined 值,但会把 NULL 渲染为 ;若要跳过空字段,需提前过滤:JSON.parse(JSON.stringify(obj, (k, v) => v == null ? undefined : v))
const { render } = require('fast-xml-parser'); const normalized = {   root: {     item: Array.isArray(parsed.root.item)        ? parsed.root.item        : [parsed.root.item]   } }; const xmlOut = render(normalized); // 避免单元素 vs 多元素歧义

解析 XML 的边界比看起来多:BOM、属性命名、兄弟节点数量、内存模型、序列化语义——这些点不提前对齐,调试时容易陷入“为什么这里没数据”的循环

text=ZqhQzanResources