CodeMirror 6 的 @codemirror/lang-xml 仅支持语法高亮,不提供自动缩进或美化功能;需集成 xml-formatter 等工具并在用户触发时调用,同时上传前必须用 DOMParser 校验 XML 合法性。
CodeMirror 6 自带的 @codemirror/lang-xml 只负责语法高亮,不提供自动缩进或美化功能。它识别标签、属性、注释,但不会重排换行或补全缩进——你粘贴一段压缩的 XML(比如 ),编辑器默认显示为单行,且无自动格式化入口。
要实现“上传前格式化”,得额外集成 XML 格式化工具,并在用户触发动作(如点击上传按钮、失焦、或 Ctrl+Shift+F)时调用它。
xml-formatter 是轻量、无依赖、支持缩进/空格/换行控制的纯 JS 库,适配浏览器环境,和 CodeMirror 6 配合最直接。
npm install xml-formatter
import { format } from 'xml-formatter';
const formatted = format(editor.state.doc.toString(), {
indentation: ' ',
collapseContent: true,
lineSeparator: '\n'
});editor.dispatch({
changes: { from: 0, to: editor.state.doc.length, insert: formatted }
});format() 会抛出 Error: Parse error,必须 try/catch 并提示用户修正Monaco 默认不内置 XML 格式化逻辑,它依赖 Language Server Protocol(LSP)或注册的 documentFormattingProvider。如果你没搭 LS,最简方案是手动注入一个客户端 formatter:
monaco.languages.register({ id: 'xml' });monaco.languages.registerDocumentFormattingEditProvider('xml', {
provideDocumentFormattingEdits(model, options) {
try {
const formatted = format(model.getValue(), {
indentation: options.insertSpaces ? ' '.repeat(options.tabSize) : '\t',
lineSeparator: '\n'
});
return [{
range: model.getFullModelRange(),
text: formatted
}];
} catch (e) {
// 不吞错:Monaco 会静默忽略返回空数组,所以这里最好弹个提示
console.warn('XML 格式化失败:', e.message);
return [];
}
}
});Shift
+Alt+F 或右键 → “Format Document” 就能触发高亮和格式化都是锦上添花,但上传失败往往卡在解析阶段。别只依赖前端美化,务必在提交前做基础合法性检查:
DOMParser 快速验证(兼容所有现代浏览器):function isValidXML(str) {
try {
new DOMParser().parseFromString(str, 'application/xml');
return !document.querySelector('parsererror');
} catch {
return false;
}
}false,说明有严重结构错误(如乱码、未闭合、非法字符),此时不应允许上传,也不该尝试格式化——因为 xml-formatter 同样会失败ActiveXObject("Microsoft.XMLDOM")
真正容易被忽略的是:格式化函数和校验函数都对 BOM、、非 UTF-8 编码敏感。如果用户从 Windows 记事本复制内容,可能带 BOM 或 \r\n 混用,建议在 format() 前先 .replace(/\r\n/g, '\n') 统一换行符。