XSLT怎么处理空白字符 xsl:strip-space

XSLT默认保留所有纯空白文本节点,需用顶层全局清理并配合精准保留必要空白,否则导致position()错乱、XPath失灵等问题。

空白字符不处理就会“乱入”结果树

XML源文件里那些换行、缩进、空格,XSLT默认全当有效节点保留——哪怕它们只是写给人看的排版。结果就是:position()算错序号、normalize-space()补救不过来、HTML输出多出空行、XPath匹配突然失灵。这不是bug,是XSLT的默认行为:**所有纯空白文本节点(只含空格/制表符/换行)都原样进入结果树**。

  • 典型现象:两个之间有换行,position()返回2和4而不是1和2
  • 根源不是你的XSLT写错了,而是处理器把换行当成了真实文本节点
  • 不是“美化输出”,而是提前从解析阶段就剔除这些无意义节点

怎么用 才真正生效

它必须是的直接子元素,且只能在顶层声明;写在里或嵌套在其他指令中完全无效。



  
  

  • elements="*" 是最安全的起点——先全局清理,再用放行需要格式的元素
  • 不要混用通配符和具体名,比如elements="* code":不同处理器解析顺序不一致,可能失效
  • 它只删“纯空白节点”,不影响 Hello 里文字前后的空格(那是混合文本的一部分)

为什么必须搭配 才可靠

你不可能真的“全删”——代码块、诗歌、配置片段一旦被扫掉缩进和换行,内容就废了。所以白名单策略才是正解:先清空,默认不留空白;再精准加回。

  • 必须写在之后,且同级
  • 当一个元素同时被两者声明时,优先——这是W3C规范明确保证的
  • 别指望靠normalize-space()后期补救:前者只能加空白,后者会吃掉所有内部空格,无法还原原始缩进

常见踩坑点:你以为删了,其实没删

最常被忽略的是作用域和时机问题——只影响**源XML解析阶段**,对模板里用拼出来的字符串、或动态生成的文本完全无效。

  • 错误写法:,但源XML里实际是(大小写敏感)
  • 错误位置:把它放在内部,等于没写
  • 混淆概念:以为它会影响——后者是输出时自动加缩进,和源空白处理无关
  • 调试技巧:用Saxon或Xalan的调试模式查看输入树(input tree),确认纯空白节点是否已被剥离

XSLT处理空白从来不是“要不要删”的选择题,而是“在哪删、为谁留、谁优先”的精确控制——漏掉,后面所有模板都可能在跟幽灵空白较劲。