Javascript is required
实现原理发布于 2026-07-28审校于 2026-08-085 分钟阅读

XML 转 JSON:浏览器 DOMParser 的解析、错误检测与非流式边界

浏览器中的 DOMParser 可以把 XML 字符串解析为 Document,再通过元素、属性和子节点构造 JSON。它适合需要 DOM 查询的中小型输入,但解析结果必须检查错误节点,且整个字符串会先进入内存;本文不提供未经测试的性能数字,也不把 DOMParser 描述成流式方案。

XML to JSONDOMParserBrowserParser Errors

一、问题概述:解析成功与业务转换是两件事

parseFromString 返回 Document 并不等于输入 XML 合法或 JSON 映射正确。浏览器可能把解析错误放进 parsererror 元素;即使没有错误,属性、重复子元素和空元素仍需要单独的转换规则。

二、最小复现:解析 XML 并检查错误节点

不同浏览器对错误文档的展示文本和 parsererror 细节可能不同,因此只把“存在错误节点”作为控制流条件,不依赖某个固定错误字符串。

function parseXml(source: string): XMLDocument {
  const document = new DOMParser().parseFromString(source, "application/xml");
  const errors = document.getElementsByTagName("parsererror");
  if (errors.length > 0) throw new Error("XML parser reported an error");
  return document;
}

const doc = parseXml("<root><item>one</item></root>");
console.log(doc.documentElement.localName); // root

三、根因:DOMParser 是整文档、非流式的 DOM 构建过程

DOMParser 接收完整字符串并构建文档树,调用方随后才能遍历节点。因此输入越大,内存和遍历成本越需要通过实际环境评估;不能从一次样例推导通用耗时,也不能在接收大量数据时假设它会逐块释放。

四、推荐方案:先验证 Document,再做明确的节点投影

把 XML 解析、parsererror 检测和 DOM→JSON 投影拆开。投影时显式处理属性、文本、重复元素和空元素;如果输入来自不可信来源,还要在业务层限制大小和允许的结构。需要真正流式处理时,应选择支持流式事件的解析方案,而不是给 DOMParser 加一个不存在的选项。

五、完整代码:将 DOM 元素投影为保守 JSON

以下函数使用元素 localName 作为键,重复子元素归并为数组,属性放在 $attributes。它只展示投影策略;生产代码仍需根据 schema 处理混合内容和命名空间。

function elementToJson(element: Element): unknown {
  const children = Array.from(element.children);
  const attributes = Object.fromEntries(Array.from(element.attributes).map((attr) => [attr.name, attr.value]));
  if (children.length === 0) {
    return Object.keys(attributes).length === 0 ? (element.textContent ?? "") : { $attributes: attributes, $text: element.textContent ?? "" };
  }
  const result: Record<string, unknown> = Object.keys(attributes).length ? { $attributes: attributes } : {};
  for (const child of children) {
    const key = child.localName;
    const value = elementToJson(child);
    result[key] = key in result ? (Array.isArray(result[key]) ? [...(result[key] as unknown[]), value] : [result[key], value]) : value;
  }
  return result;
}

六、常见错误方案

只读取 textContent 会丢失属性和嵌套元素;看到 parsererror 就读取固定英文文案会在不同浏览器中失效;把所有子元素按 nodeName 合并会把不同 namespace 的同名元素混在一起。把 DOMParser 当作流式解析器也会造成错误的内存预期。

七、边界条件:空元素、CDATA 与命名空间

<item/> 的 textContent 为空,不代表它一定应转换为空字符串;CDATA 在 DOM 中通常作为文本内容呈现,若要保留表示形式需要额外约定。命名空间场景应使用 namespaceURI/localName,而不是只看带前缀的 nodeName。

八、如何验证解析与投影

分别测试合法 XML、未闭合标签、错误嵌套、空元素、属性、重复节点、CDATA 和 namespace。断言错误输入被拒绝、合法 Document 的根节点正确、重复键归并为数组,并在目标浏览器中记录实际内存行为,而不是填写猜测的耗时数据。

九、FAQ

问:DOMParser 会返回 null 表示 XML 错误吗?答:浏览器通常返回带错误信息的 Document,错误节点和文案存在实现差异,应按文档检查。

问:DOMParser 能边下载边解析吗?答:它接收完整字符串,不是流式 API;需要流式处理应选用相应解析器。

问:为什么解析成功还要做 schema 验证?答:XML well-formed 只保证语法,不保证字段、基数和业务类型。

十、总结

浏览器 XML→JSON 的流程是完整字符串进入 DOMParser、检查 parsererror、再按明确规则遍历 DOM。DOMParser 是非流式整文档模型,不能编造性能承诺;属性、重复元素、空值和 namespace 必须由投影契约处理。

来源与延伸阅读

技术审校所依据的规范与权威参考资料。

相关文章

继续阅读

可打开关联的浏览器工具,使用自己的样本验证文中的处理流程。

打开关联工具