XML 出问题的典型表现有两种:浏览器打开只显示「错误行」,或者看起来正常但导入系统时被拒。前者是语法坏了,后者往往是内容语义不对 —— 这两种情况要分开处理。
校验能查出哪五类错
XML 转换 的检查范围是明确的五项:标签闭合与嵌套顺序、属性引号是否成对、是否只有一个根元素、注释与 CDATA 是否正确闭合、实体引用是否合法,并给出行号与列号。
这五项覆盖的是 well-formed(格式良好)判定。其中最常被忽略的是「只有一个根元素」:两个并列的根节点在片段里很常见,浏览器会直接报错,而复制粘贴时看不出问题。
明确不做的三件事
不联网获取外部 DTD 与外部实体。不做 DTD/Schema 有效性校验,也就是不判断「这个字段该不该出现、类型对不对」。不做 XSLT 转换。
这三条边界很重要:很多「XML 校验通过但系统仍然拒收」的情况,原因就在 Schema 层,而不是格式层。校验通过只代表语法没错。
一个刻意的设计:混合内容不拆行
格式化按嵌套层级缩进(2 空格、4 空格或 Tab),但元素与文字交错的混合内容整块保持在同一行。
这不是偷懒 —— XML 里的空白是有语义的,把 <p>这是<strong>加粗</strong>的文字</p> 拆成三行,读出来就多了两个换行符,转换反而改坏了内容。所以这类节点整块保留,避免改动语义。
同理,压缩只去掉标签之间的空白与换行,文本节点内部的空格不动。
几 MB 的文件为什么不卡
这一页用自写的事件式解析器逐字符扫描,不用浏览器自带的 DOMParser。差别在于:DOMParser 要把整棵树建进内存并保留对象,几 MB 的文件就能让页面失去响应几十秒;逐字符扫描只维护当前位置与栈。
但显示层仍然有限制:内容超过 5000 行或 200KB 时,输入输出框只显示前 500 行预览,处理与下载按完整内容执行。文件建议 20MB 以内。
顺手能用的两个提取
属性提取会列出「元素路径 → 属性名 = 值」的清单,可导出为 CSV 或 JSON。排查命名空间、编码声明这类信息时特别有用 —— 它们都在属性里,肉眼看大文件基本找不到。
CDATA 提取按出现顺序导出所有 CDATA 段的文本内容。嵌在 CDATA 里的 HTML、脚本、长说明文字,用这个能一次全捞出来,不用手抄。
一个真实用途:数电票的 XML
下载的电子发票常常是 XML 格式(发票数据本身,不是给人看的版式)。这一页能校验它是否完整、用属性提取看关键字段、用 CDATA 提取捞内容。但要打印或提交,需要的是 PDF 或 OFD 版式文件,那是另一件事,见 OFD 文件是什么?打不开、转不成 PDF 的完整解决办法 和 OFD 格式的电子发票怎么变成能打印能提交的 PDF?。
全程在浏览器本地完成,文件不上传服务器、不占每日转换次数、也不需要登录 —— 含企业信息的报文可以放心处理。