Node.js如何解析XML xml2js库使用方法

Node.js需借助xml2js库实现XML与JS对象互转:解析时通过Parser配置ignoreAttrs、attrkey等选项优化结构,推荐使用parseStringPromise;序列化用Builder控制headless和pretty格式。

Node.js 本身不内置 XML 解析能力,常用 xml2js 库将 XML 字符串转为 JavaScript 对象(反序列化),也支持将对象转回 XML(序列化)。它轻量、灵活,适合大多数常规 XML 处理场景。

安装 xml2js

在项目根目录下运行:

  • npm install xml2js

基础解析:XML 字符串 → JS 对象

默认情况下,xml2js 会把 XML 转成嵌套的 JS 对象,但属性和文本内容需手动区分。推荐启用常用选项提升可读性:

  • ignoreAttrs: false —— 保留属性(默认忽略)
  • attrkey: '$' —— 属性存入 $ 字段(如 { $: { id: "123" } }
  • charsAsItems: true —— 文本内容统一用 _ 字段表示(避免与子元素名冲突)
  • explicitArray: false —— 单个子元素不强制包装成数组(更符合直觉)

示例代码:

const xml2js = require('xml2js');

const xml = `
  
    Alice
    30
  
`;

const parser = new xml2js.Parser({
  ignoreAttrs: false,
  attrkey: '$',
  charsAsItems: true,
  explicitArray: false
});

parser.parseString(xml, (err, result) => {
  if (err) throw err;
  console.log(result);
  // 输出:{ root: { user: { $: { id: "1001", role: "admin" }, name: { _: "Alice" }, age: { _: "30" } } } }
});

简化访问:使用 parseStringPromise(推荐)

v0.5+ 支持 Promise API,避免回调嵌套:

const { parseStringPromise } = require('xml2js');

async function parseXML(xmlStr) {
  try {
    const result = await parseStringPromise(xmlStr, {
      ignoreAttrs: false,
      attrkey: '$',
      charsAsItems: true,
      explicitArray: false
    });
    return result;
  } catch (err) {
    throw new Error('XML 解析失败:' + err.message);
  }
}

// 使用
parseXML(xml).then(console.log);

生成 XML:JS 对象 → XML 字符串

Builder 类反向构造:

const { Builder } = require('xml2js');

const obj = {
  root: {
    user: {
      $: { id: "1001", role: "admin" },
      name: { _: "Alice" },
      age: { _: "30" }
    }
  }
};

const builder = new Builder({ headless: true, renderOpts: { pretty: true } });
const xml = builder.buildObject(obj);
console.log(xml);
// 输出格式化 XML 字符串

注意:headless: true 不生成 XML 声明(如 ),按需开启;pretty: true 启用缩进。

常见问题处理

中文乱码?
确保原始 XML 字符串是 UTF-8 编码(Node.js 默认支持),若从文件读取,用 fs.readFileSync(path, 'utf8') 显式指定编码。

空标签或自闭合标签?
xml2js 默认能正确识别 ,解析后对应空对象或 null,取决于是否含属性。

同名多个子元素?
若设 explicitArray: true(默认),则自动转为数组;设为 false 时,仅当实际存在多个才转数组,单个保持对象 —— 更安全,推荐后者。