XML 注释与处理指令
本章定位 :掌握 XML 注释的严格规则(禁止
--、禁止嵌套)和处理指令的应用场景(xml-stylesheet等)。
定义与作用
XML 注释 用于在文档中添加人类可读的说明,解析器会忽略注释内容。
处理指令 (Processing Instruction,PI)是向处理 XML 文档的 特定应用程序 传递指令的机制。最常见的处理指令是 <?xml-stylesheet?>,它告诉浏览器如何用 CSS 或 XSLT 渲染 XML 文档。
两者的本质区别:
- 注释是给人看的,解析器直接跳过
- 处理指令是给应用程序看的,解析器会传递给应用
核心原理:解析器对注释和 PI 的处理
图解释 :XML 解析器对注释和 PI 有专门的状态机。注释中一旦发现 -- 后不是 > 就报 fatal error。PI 的内容不验证,直接传给目标应用。
语法/结构要点
注释规则
| 规则 | 说明 |
|---|---|
| 语法 | <!-- 注释内容 --> |
禁止 -- | 注释内容中不能出现连续的两个短横线 |
| 禁止嵌套 | 注释不能包含另一个注释 |
| 不能放在标签内 | 注释不能出现在标签内部 |
| 不能在声明前 | 注释不能出现在 XML 声明之前 |
处理指令
| 指令 | 用途 | 示例 |
|---|---|---|
xml-stylesheet | 关联 CSS 或 XSLT 样式表 | <?xml-stylesheet type="text/css" href="style.css"?> |
xml-model | 关联 Schema(用于验证) | <?xml-model href="schema.rng"?> |
| 自定义 PI | 应用程序专用指令 | <?php echo "Hello";?> |
完整示例:白歌为乐途图书目录绑定样式
场景说明
飞翔科技架构师 白歌 写了一个图书目录 XML,希望直接在浏览器中查看时能显示为漂亮的表格,而不是 XML 源码树。她的方案是:用 xml-stylesheet 处理指令关联一个 XSLT 样式表。
操作前:无样式的 XML(浏览器显示源码树)
<?xml version="1.0" encoding="UTF-8"?>
<bookstore>
<book category="web">
<title lang="en">Learning XML</title>
<author>Erik T. Ray</author>
<year>2003</year>
<price>39.95</price>
</book>
<book category="cooking">
<title lang="en">Everyday Italian</title>
<author>Giada De Laurentiis</author>
<year>2005</year>
<price>30.00</price>
</book>
</bookstore>
浏览器中显示为可折叠的 XML 源码树——对普通用户不可读。
操作后:添加处理指令
<?xml version="1.0" encoding="UTF-8"?>
<!-- 飞翔科技图书目录 - 白歌 2026 -->
<?xml-stylesheet type="text/xsl" href="bookstore.xsl"?>
<bookstore>
<!-- ====== Web 类图书 ====== -->
<book category="web">
<title lang="en">Learning XML</title>
<author>Erik T. Ray</author>
<year>2003</year>
<price>39.95</price>
</book>
<!-- ====== 烹饪类图书 ====== -->
<book category="cooking">
<title lang="en">Everyday Italian</title>
<author>Giada De Laurentiis</author>
<year>2005</year>
<price>30.00</price>
</book>
</bookstore>
配套的 bookstore.xsl:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<html><body>
<h2>飞翔科技图书目录</h2>
<table border="1">
<tr bgcolor="#9acd32">
<th>书名</th><th>作者</th><th>年份</th><th>价格</th>
</tr>
<xsl:for-each select="bookstore/book">
<tr>
<td><xsl:value-of select="title"/></td>
<td><xsl:value-of select="author"/></td>
<td><xsl:value-of select="year"/></td>
<td><xsl:value-of select="price"/></td>
</tr>
</xsl:for-each>
</table>
</body></html>
</xsl:template>
</xsl:stylesheet>
操作结果
浏览器读取 XML 时发现 <?xml-stylesheet?> 指令,自动加载 XSLT 样式表,将 XML 转换为 HTML 表格渲染。用户看到的不是源码,而是格式化的图书目录表。注释则被解析器忽略,不影响渲染但保留了代码可读性。
易错场景
错误一:注释中有双连字符
<!-- ❌ 注释中不能有 -- -->
<!-- 这个正则 -- 匹配多个短横 -->
<!-- ✅ 如果必须出现横线,用其他方式分隔 -->
<!-- 这个正则匹配多个短横线 -->
错误二:注释嵌套
<!-- ❌ 注释不能嵌套 -->
<!-- 外层注释 <!-- 内层注释 --> 回到外层 -->
<!-- ✅ 分开写 -->
<!-- 外层注释 -->
<!-- 内层注释 -->
错误三:处理指令放错位置
<?xml version="1.0" encoding="UTF-8"?>
<root>
<?xml-stylesheet type="text/xsl" href="style.xsl"?> <!-- ✅ 可以 -->
<child>
<?xml-stylesheet ...?> <!-- 可以但无意义,浏览器只看文档开头的 PI -->
</child>
</root>
虽然语法允许 PI 出现在任何位置,但 xml-stylesheet 通常放在文档开头附近。
面试考点
| 考点 | 参考答案要点 |
|---|---|
XML 注释中为什么不能包含 --? | XML 规范规定注释内容不能包含连续两个短横线,这是为了保持与 SGML 的兼容性(SGML 注释语法更复杂)。这是语法硬限制,不是建议 |
| 处理指令和注释的本质区别是什么? | 注释被解析器丢弃,处理指令被传递给应用程序。注释是给人看的,PI 是给程序看的 |
<?xml-stylesheet?> 是唯一的标准处理指令吗? | 不是。它是 W3C 推荐的但并非强制。xml-model 也是标准 PI。任何应用都可以定义自己的 PI(如 PHP 用 <?php ...?>) |