SaxonJ-HE 11.3执行XSLT恒等转换时为何删除XML空行?
问题描述
现有如下"identity transform(恒等转换)"XSLT代码:
<?xml version="1.0" encoding="UTF-8"?> <xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0"> <xsl:output encoding="UTF-8" method="xml" indent="yes" media-type="application/xml"/> <xsl:template match="@*|node()"> <xsl:copy> <xsl:apply-templates select="@*|node()"/> </xsl:copy> </xsl:template> </xsl:transform>
对应的输入XML内容如下:
<?xml version="1.0" encoding="UTF-8"?> <Foobar xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:transform version="2.0"> <!-- Parameters --> <xsl:param name="param1"/> <xsl:param name="param2"/> <xsl:param name="param3"/> <!-- Variables --> <xsl:variable name="variable1" select="'abc'"/> <xsl:template match="/*"> </xsl:template> </xsl:transform> </Foobar>
使用SaxonJ-HE 11.3版本执行上述转换时,输出结果中原XML包含的空行被删除,对应差异对比如下:
$ saxon -xsl:transform.xsl -s:input.xml | diff -u input.xml - --- input.xml 2022-06-16 16:26:41.000000000 -0400 +++ - 2022-06-16 16:28:42.000000000 -0400 @@ -6,12 +6,9 @@ <xsl:param name="param1"/> <xsl:param name="param2"/> <xsl:param name="param3"/> - <!-- Variables --> <xsl:variable name="variable1" select="'abc'"/> - <xsl:template match="/*"> </xsl:template> - </xsl:transform> </Foobar>
请问SaxonJ-HE 11.3执行恒等转换时删除空行的具体原因是什么?
原因说明
核心原因是属于XSLT命名空间的空白文本节点,会被Saxon默认判定为样式表格式空白直接剥离,不会作为普通输入节点进入转换流程,具体逻辑如下:
- 你的输入XML在
<Foobar>根节点上声明了XSLT的标准命名空间http://www.w3.org/1999/XSL/Transform,内部嵌套的<xsl:transform>及其所有子元素都属于这个命名空间。 - Saxon解析输入XML时,会对XSLT命名空间下的节点做特殊的语义预处理:元素之间只包含换行、空格的空白文本节点(也就是你看到的那些空行),会被认定为编写XSLT时用来排版的无意义格式空白,直接在构建XPath数据模型树的阶段就剔除,根本不会进入后续转换逻辑。
- 恒等转换的逻辑是复制数据模型树里存在的所有节点,这些在解析阶段就被删掉的空白节点,自然不可能被复制到输出里。
- 你在样式表里设置了
indent="yes",输出的缩进是Saxon序列化阶段重新生成的,针对XSLT命名空间内的元素,序列化规则不会主动额外插入空行,最终就出现了你看到的空行丢失的差异。
如果需要保留这些空行,执行Saxon命令时加上--strip-space:none参数,关闭默认的空白剥离逻辑即可。
内容的提问来源于stack exchange,提问作者Archie
相关产品推荐
相关产品推荐

