用别的工具格式化 XML 后再跑,程序取到的文本前后多了空格——问题就出在混合内容上。「XML转换」的格式化按嵌套层级缩进,但元素与文字交错的节点会整块保持在同一行,不做拆行。这不是排版偷懒,是为了不改动你解析出来的值。
为什么这一行不能拆
XML 里元素之间的空白是有内容的。同一个段落内混着强调标签、链接标签和正文时,换行会变成文字的一部分:原本读出来是「请阅读用户协议并确认」,拆行后变成中间夹着换行的三段,拼回去就是断句错乱。带命名空间的文档、以及依赖空白做分隔的公式或诗句,表现更明显。
所以判断标准很直接:这个元素内部只有子元素,就往下缩进;一旦文字和标签交错,整块留在原行。代价是这类节点行很长(比如一整段带若干内联标签的说明文字),看起来不够整齐。想让它变短只能改文档结构,而不是指望格式化工具替你折行。
校验查什么、给什么
校验范围是明确的五项:标签闭合与嵌套顺序、属性引号是否成对、是否只有一个根元素、注释与 CDATA 段是否正确闭合、实体引用是否合法。每一项都给出行号和列号。
这套检查用的是自写的事件式解析器逐字符扫描,不依赖 DOMParser,所以几 MB 的文件也不会让页面长时间失去响应,报错位置也能精确到列。定位效率最高的一类错误是嵌套顺序反了:结束标签交叉(先开的标签后关),行号会指向那个错位的结束标签,而不是真正漏关的位置,需要往前找同名开始标签配对。
它明确不做的三件事
不联网获取外部 DTD 与外部实体。文档里声明了外部实体的,这里不会去取,相关引用只做字面处理。不做 DTD 或 Schema 的有效性校验——元素该不该出现、顺序对不对、属性缺没缺,只要语法合法全部放过。不做 XSLT 转换,样式表渲染请回原系统。
因此「校验通过」的真实含义只是这份文件是一份结构良好的 XML,不代表业务方能接受它。政务对接、老系统导入这类场景,必须拿实际接口跑一遍才算验收。
建议的处理顺序
- 上传或粘贴,先执行校验,把行列号记下来。
- 有错先修错,别在报错状态下格式化——输出可能是半截结构。
- 校验通过后执行格式化,重点看长行是不是混合内容,是就别拆。
- 下载后用接收方的解析器再读一次,确认取值没有多出或缺少空白。
什么时候别用格式化:文件是要送去签名或做哈希比对的,任何空白改动都会让校验失败,这种要保持原始字节不动。更多排查思路见 XML 在线格式化与校验,工具入口在 XML转换。