将Markdown内容转换为XML格式

Markdown转XML无统一标准,必须先明确目标XML结构和用途;不能直接用markdown-it或marked,因其不保证XML良构性;推荐用remark-parse解析为AST后,以xmlbuilder2按需构建XML。

Markdown 转 XML 没有统一标准,必须先明确目标 XML 的结构和用途——是用于文档归档(如 DocBook)、网页渲染(如 XHTML),还是自定义数据交换格式?直接套用通用转换器大概率会失败。

为什么不能用 markdown-itmarked 直接生成 XML?

这些库默认输出 HTML 字符串,即使开启 html: false 也只是禁用内联 HTML 标签,仍会保留非 XML 兼容的转义(如  )或缺失 XML 声明与根元素。更关键的是:它们不校验标签闭合、不处理命名空间、也不保证属性值被双引号包裹——而这些都是良构 XML 的硬性要求。

xmlbuilder2 + 手动解析 Markdown AST 最可靠

推荐流程:用 remark-parse 解析 Markdown 为统一 AST(unist 树),再遍历节点,用 xmlbuilder2 构建符合你 Schema 的 XML。这样能完全控制每个节点的映射逻辑,比如:

  • heading 节点 →

    ,取决于你的 DTD
  • list 节点 → 强制用
      /
        ,而非自定义
      1. inlineCode → 包裹在 中,而非裸文本

      示例片段(将一级标题转为 ):

      const { remark } = await import('remark');
      const { xml } = await import('xmlbuilder2');
      

      const md = '# Hello World'; const tree = (await remark().use(() => {}).parse(md));

      const doc = xml({ version: '1.0', encoding: 'UTF-8' }); const root = doc.ele('document');

      function walk(node) { if (node.type === 'heading' && node.depth === 1) { const title = node.children[0]?.value || ''; root.ele('doc-title').txt(title); } } walk(tree);

      console.log(doc.end({ prettyPrint: true })); // 输出: // // // Hello World //

      警惕 pandoc 的隐式行为

      pandoc -f markdown -t

      docbook 看似便捷,但它依赖内置模板,且:

      • 会自动插入
      等语义化标签,无法关闭
    • 对中文标点、脚注、自定义容器(如 :::warning)支持不稳定
    • 输出含 xmlnsrole 属性,若下游系统不认这些命名空间,解析会报错
    • 如果只是临时导出,加 --wrap=none --standalone 可减少干扰;但生产环境建议绕过 pandoc,走 AST 路线。

      真正难的不是语法转换,而是决定每个 Markdown 语义单元对应哪个 XML 元素——这个映射规则一旦定错,后续所有 XSLT 或 XPath 都得重写。