XML prolog(序言)是指XML文档中位于根元素开始标签之前的那一部分内容,它并不是一个具体的标签,而是对文档开头声明区域的统称。一个完整的prolog通常包含XML声明和文档类型声明(DTD)两块内容。很多人写了多年XML却从未认真研究过这段开头的文字,直到遇到乱码、解析器报错或者Schema校验失败时才回过头来补课。理解prolog的结构和规则,是写出合法XML文档、排查解析问题的基础。

XML prolog的基本结构是什么
从XML规范的角度看,一份XML文档由prolog和根元素两大部分组成。prolog位于文档最顶端,可以包含XML声明、处理指令、注释、空白符以及文档类型声明(DOCTYPE)。其中XML声明最为常见,几乎所有XML文档的第一行都是它。一个典型的例子如下:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<!DOCTYPE books SYSTEM "books.dtd">
<!-- 这是prolog中的注释 -->
<books>
<book id="1">XML入门</book>
</books>上面的前三行都属于prolog区域,从<books>开始才是文档的根元素,也就是文档的主体内容。需要特别注意的一点是,XML声明如果存在,就必须出现在文档的第一行第一列,前面不能有任何空格、空行或者BOM字符。曾经有开发者把XML文件从数据库导出时,程序在开头多输出了一个空行,结果解析器直接抛出“Content is not allowed in prolog”的异常,这个报错信息里提到的prolog就是本文讨论的这段区域。
prolog本身是可选的。XML 1.0规范并没有强制要求文档必须写XML声明,如果整个文档使用UTF-8或UTF-16编码,理论上可以省略声明。但在实际工程中,强烈建议显式写出声明,因为它能明确告诉解析器文档的版本和编码,避免不同环境下的解析歧义。
XML声明包含哪三个重要属性
XML声明的写法固定为<?xml ... ?>,其中问号和xml之间不能有空格,这是很多人容易写错的地方。声明内可以携带三个属性,分别是version、encoding和standalone,它们的顺序不能颠倒。
第一个是version属性,它声明文档遵循的XML规范版本,目前合法的取值只有1.0和1.1。绝大多数场合都使用1.0,因为XML 1.1只在字符处理规则上做了少量扩展,各大解析器和工具链对它的支持反而不够统一,除非有明确需求,否则不建议使用1.1。
第二个是encoding属性,它告诉解析器文档本体采用什么字符编码。如果不写,解析器会默认按UTF-8处理。这个属性是引发乱码问题的高发地带,例如一个文件实际以GBK编码保存,声明里却写着UTF-8,解析器就会按照声明去解码,中文内容会全部变成乱码或者直接解析失败。下面是一个指定GBK编码的例子:
<?xml version="1.0" encoding="GBK"?>
<note>
<to>张三</to>
<from>李四</from>
</note>encoding属性的取值必须是IANA注册的编码名称,常见的有UTF-8、GBK、GB2312、ISO-8859-1等。注意名称大小写在XML规范中是不敏感的,utf-8和UTF-8效果相同,但为了规范统一,建议统一使用大写形式。
第三个是standalone属性,它是一个只取yes或no的开关,表示文档是否依赖外部标记声明。当取值为yes时,表示文档完全自包含,不需要读取外部DTD;取值为no时表示可能依赖外部的DTD或参数实体。这个属性只对有外部DTD的场景有实际意义,没有DOCTYPE的普通文档写不写它几乎没有任何影响,因此实践中经常省略。
DOCTYPE声明与prolog的关系是什么
很多人会把DOCTYPE和XML声明混为一谈,其实它们是prolog中两个独立的部分。XML声明是<?xml ... ?>形式的处理指令样式声明,而DOCTYPE是<!DOCTYPE ... >形式的文档类型声明,后者用于告诉解析器文档的根元素名称以及DTD的位置。例如Spring框架早期的配置文件第一行之后往往会看到:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN 2.0//EN"
"http://www.springframework.org/dtd/spring-beans-2.0.dtd">
<beans>
<bean id="userService" class="com.example.UserService"/>
</beans>DOCTYPE可以引用内部DTD(用方括号包裹的声明集合),也可以通过SYSTEM指向本地DTD文件,或者通过PUBLIC配合公共标识符和系统标识符指向网络上的DTD。在使用XML Schema(XSD)校验的场景中,DOCTYPE通常会被省略,因为Schema的引用是写在根元素上的xmlns和xsi:schemaLocation属性中,而不是放在prolog里。
另外要注意,处理指令(比如常见于样式表关联的<?xml-stylesheet type="text/xsl" href="style.xsl"?>)和注释也可以出现在prolog中,位置在XML声明之后、DOCTYPE之前或之后均可,但绝对不能出现在根元素之后。掌握这些顺序规则后,无论是手工编写XML配置文件还是程序生成XML输出,都能有效避免格式层面的低级错误,排查起“Content is not allowed in prolog”这类报错时也能快速定位到问题根源。
XML序言XML声明encoding编码修改时间:2026-09-08 20:22:57