createElement 创建 XML 节点必须用 document.createElementNS;动态添加属性须用 setAttributeNS;文本内容需用 createTextNode;序列化须用 XMLSerializer.serializeToString。
HTML5 环境下直接调用 document.createElement 生成的节点属于 HTML 命名空间,即使你把它 append 到 XML 文档里,也会被浏览器当作 HTML 元素处理——比如自动闭合 self-closing 标签、忽略大小写、强制转义属性值。真正的 XML 节点必须显式声明命名空间。
document.createElement("book") → HTML 元素,不适用于 XML 文档document.createElementNS("http://www.w3.org/1999/xhtml", "book") → XHTML
元素(仍非纯 XML)document.createElementNS(null, "book") → 正确!null 表示无命名空间的纯 XML 元素XML 对属性命名敏感,尤其含冒号前缀(如 xml:lang)或需保留大小写时,setAttribute 会失败或静默降级。必须用 setAttributeNS 并传入正确的命名空间 URI(多数情况为 null)。
node.setAttributeNS(null, "id", "b001")
node.setAttribute("ID", "b001") → 属性名可能被小写化,且无法支持带命名空间前缀的属性node.setAttributeNS("http://www.w3.org/XML/1998/namespace", "xml:lang", "en")
XML 不支持 innerHTML,强行设置会触发 HTML 解析器,导致尖括号被转义、实体被展开、结构错乱。所有文本内容必须走 createTextNode 并用 appendChild 插入。
const title = doc.createElementNS(null, "title");
const text = doc.createTextNode("Learning in 2025");
title.appendChild(text); // ✅ 安全保留原始字符
// title.innerHTML = "Learning in 2025"; // ❌ 错误:XML 文档不支持 innerHTML
XML 节点没有 outerHTML 属性;尝试读取会返回 undefined 或空字符串。要获取 XML 字符串,必须用 XMLSerializer 实例的 serializeToString 方法。
new XMLSerializer().serializeToString(node) → 返回标准 XML 字符串(含正确缩进、编码、声明)node.outerHTML → 在 XML 文档中始终不可用serializeToString 不会自动添加 ,如需声明需手动拼接createElementNS(null, ...) 中那个看似多余的 null 参数——它恰恰是区分 HTML 和 XML 节点的开关。