注释写给人(
<!-- ... -->),处理指令写给程序(<?目标 指令?>),CDATA 段则是不想转义的大段文本的安全舱。三者都不是数据本体,却各有明确受众与禁忌。本节合并解剖这三条旁白通道(原教程的处理指令一节并入此处),并把最容易踩的双连字符雷区演示一遍。
<config> <!-- 生产环境每分钟限流 600 次;压测环境可调至 6000 --> <rate limit="600" window="60s"/> </config>
语法规则很短:以 <!-- 开始、--> 结束;内容中不允许出现两个连续连字符;不能嵌套;不能出现在声明之前。第二条最阴险——
<!-- 灰度计划:-- 首批 5%,观察 24h --> <!-- 解析器读到第二个 -- 就认为注释结束,后面变成非法内容,整份文档报错 --> <!-- 正确写法:把双连字符改成"至"或空格 -->
另外,注释虽然"解析器不处理",但会原样随文档传输。生产报文里的注释被对方系统看到不是 Bug 而是常态,敏感信息(密钥提示、内部代号)别写进去。程序读取注释内容的 API 也存在(DOM 的 Comment 节点),所以更准确的说法是"解析器不把注释当数据",而不是"注释绝对不可见"。
背景场景:要在 XML 里嵌一段示例代码或含大量尖括号的文本。操作对照:
<!-- 方式一:逐个转义,可读性崩塌 --> <sample><xsl:template match="/">...</xsl:template></sample> <!-- 方式二:CDATA 段,内部字符原样保留 --> <sample><![CDATA[ <xsl:template match="/">...</xsl:template> ]]></sample> <!-- CDATA 以 <![CDATA[ 开始、]]> 结束;内部不允许出现 ]]> 这个序列 -->
解读:CDATA 不是"注释的另一种写法",它是内容的一部分——解析后 sample 元素的值就是那段原始文本,会被下游取用;注释则根本不进入数据树。两者的混淆是常见错误。变式:若文本里恰好要包含 ]]>(比如嵌另一段 XML 教程),只能拆成两段 CDATA,把 offending 序列断开。另有一条位置约束值得记:CDATA 段只能出现在元素内容里,属性值与文档 prolog 区都不接受——属性想免转义没有安全舱,只能老实写实体,这又印证了 2.3 节"属性只装简单值"的边界。
处理指令(Processing Instruction,PI)的语法是 <?目标 数据?>,目标是要接收指令的应用名。最常见的一条:
<?xml version="1.0" encoding="UTF-8"?> <?xml-stylesheet type="text/xsl" href="catalog.xsl"?> <catalog> <book><title>算法导论</title></book> </catalog> <!-- 浏览器打开这份文档时,会按 catalog.xsl 的规则把它渲染成 HTML -->
xml-stylesheet 是 W3C 定义的标准处理指令,用途是把文档与样式表挂钩。注意它出现在根元素之前、XML 声明之后。声明本身 <?xml ...?> 在语法外形上像 PI,但它是声明、不是 PI——目标名 xml 被保留。
工具也可以自定义 PI。历史上微软的 Word 用 mso-application PI 标记"本文件请用 Word 打开",让保存成 .xml 的文档双击时进入 Word 而不是浏览器。工程上自造 PI 要克制:双方系统不认识它就是废字节,还占传输量。
| 通道 | 受众 | 语法 | 是否进入数据树 | 高频雷区 |
|---|---|---|---|---|
| 注释 | 人 | <!-- --> |
否(可单独读取) | 双连字符、嵌套 |
| CDATA | 数据本身 | <![CDATA[ ]]> |
是 | 内容含 ]]> |
| 处理指令 | 特定程序 | <?目标 数据?> |
否(DOM 有独立节点) | 与声明混淆 |
实战检查单:发布报文前搜索一遍 <!--,确认没有夹带内部注释;含示例代码的字段统一走 CDATA;PI 只保留双方约定的那几条。
💡 记法:注释是便利贴,CDATA 是防弹玻璃箱,PI 是写给特定机器的工作指令单——三者都在文档里,只有防弹箱里的东西算货物。
三条通道都合法,不代表都能随便用。给团队定旁白纪律,可以参考三条规定。其一,注释写"为什么"不写"是什么":代码本身已说明是什么,注释的价值在解释决策背景——"此处顺序不能调,因对方系统按位置取值"是有价值的注释,"这是一个价格元素"是噪音。其二,CDATA 只包真正的特殊文本,不为省几个转义符滥用——CDATA 段在许多工具里不可折叠、不可高亮内层语法,可读性其实更差。其三,处理指令须登记:自造 PI 前先确认消费方真的认识它,并在接口文档登记目标名,否则它就是文档里的幽灵字节。
还有一条跨通道的通用纪律:旁白内容不计入契约。DTD 与 XSD 默认不约束注释与 PI 的存在与否,校验通过不代表旁白符合预期。如果双方约定了"报文必须带某条 PI",要么写进人工规范,要么升级为真正的元素——旁白通道不适合承载强约束的业务语义,它的定位从设计上就是"数据本体之外"。同理,也别指望用注释做"字段说明"传给下游——多数解析路径根本不读注释,说明性信息要进数据就老老实实做元素或属性,要给人看就放接口文档。通道各司其职,混用必出悬案。
]]> 必须断开;xml-stylesheet 关联样式表最常用;至此骨架四构件全部解剖完毕。文档"形状正确"了,但形状正确不等于合格——质检车间的两道检验规程在下一章开工。