XML的空白字符(Whitespace)处理规则是什么,解析器如何对待换行和缩进?

7次阅读

xml解析器对空白字符的处理取决于内容模型、xml:space属性及解析器策略;默认执行规范化(换行缩进变空格、压缩多空、首尾剥离),仅mixed content或xml:space=”preserve”可保留原始空白。

XML的空白字符(Whitespace)处理规则是什么,解析器如何对待换行和缩进?

xml解析器对空白字符的处理取决于这些空白是否出现在元素内容中,以及元素是否被声明为mixed content(混合内容)或具有特定的xml:space属性。换行和缩进本身不是语法错误,但是否保留、忽略或规范化,由上下文和解析器策略共同决定。

默认情况下:空白可能被“规范化”或“忽略”

根据XML 1.0规范,解析器在读取标记内容(character data)时,会执行空白规范化(whitespace normalization)

  • 将所有制表符(t)、回车(r)、换行(n)统一视为空格字符( );
  • 将连续多个空白字符(包括换行缩进)压缩为单个空格;
  • 开头和结尾的空白会被剥离(trim),除非该元素被定义为preserved whitespace

这种行为只适用于element content(即元素标签之间的纯文本,且该元素在DTD或Schema中被声明为仅含子元素、不含混合文本)。例如:

  Hello    world

默认解析后,文本内容通常变成"Hello world"(首尾去空、中间多空变一空)。

如何保留换行和缩进:使用xml:space="preserve"

可在任意元素上显式声明xml:space="preserve",告诉解析器:该元素及其所有后代中的所有空白字符(包括换行、缩进、多个空格)都应原样保留。

  • 这是W3C标准支持的机制,无需依赖特定解析器扩展;
  • 常用于
    
    

    类语义的XML元素;

  • 例如: a = 1;n b = 2;,解析后仍含原始缩进与换行。

Schema/DTD影响:内容模型决定空白是否“有意义”

如果一个元素在DTD或XML Schema中被定义为EMPTYelement-only(如),那么其中出现的纯文本(包括换行缩进)属于“意外字符数据”,解析器通常会将其视为ignorable whitespace并直接丢弃。

  • 只有当元素允许mixed content(如)时,内部的换行缩进才可能作为#PCDATA的一部分被保留(但仍受上述规范化规则约束,除非加xml:space);
  • 现代Schema语言(如XSD)中,可通过whiteSpace facet(值为preservereplacecollapse)进一步控制具体文本字段的处理方式。

实际开发中的建议

不要依赖格式化空白“自动保留”。若需可靠控制:

  • 对需要原样展示的内容,显式添加xml:space="preserve"
  • 避免在结构型元素(如)内混入无意义的换行缩进,以免不同解析器行为不一致;
  • 使用dom/SAX等API时,注意其默认配置:某些库(如java的DocumentBuilder)默认忽略可忽略空白,需调用setIgnoringElementContentWhitespace(false)才能获取全部文本节点;
  • 调试时可用isWhitespaceInElementContent()(DOM Level 3)等方法判断某文本节点是否仅为规范化的空白。

基本上就这些。核心是:XML不把换行缩进当语法成分,是否保留,得看内容模型+显式声明+解析器设置。

text=ZqhQzanResources