Saxon HE9.9连续空白xsl:text输出被抑制问题求助
这个问题我之前也碰到过,本质是Saxon对纯空白文本节点的默认处理逻辑和你本地测试工具(Liquid Studio)不一样导致的。当两个相邻的<xsl:text>里只有空白字符时,Saxon会默认把它们合并成一组空白,这就导致你需要8个空格时只输出了4个,进而破坏了MARCXML的008字段格式。
问题根源
Saxon遵循XSLT的空白处理规范,对于连续的纯空白文本节点,在序列化阶段会自动压缩合并。你的本地工具可能默认启用了更严格的空白保留策略,而服务器上的Saxon命令行没有配置相关参数,所以出现了差异。
几种可行的解决方案
1. 配置序列化参数强制保留空白
最直接的方法是在XSLT中添加<xsl:output>元素,明确指定要保留空白:
<xsl:output method="xml" indent="no" preserve-space="controlfield"/>
这里preserve-space="controlfield"是因为008字段属于MARCXML里的<controlfield>元素,指定这个元素后,它内部的空白会被完整保留。
如果你不想修改XSLT,也可以直接在Saxon命令行中传递序列化参数:
"D:\Program Files\Saxonica\SaxonHE9.9N\bin\Transform" -s:"\\fileshare.lacaws02.local\goanywhere\data\Test008\mods2marc-In 2.xml" -xsl:\\fileshare.lacaws02.local\goanywhere\Lib\MODS\MODS3-4_TO_MARC21slim_XSLT16.xsl -o:\\fileshare.lacaws02.local\goanywhere\userdata\workspace\1000000000114\Output.xml !method=xml !preserve-space=controlfield !indent=no
注意Saxon的序列化参数需要加!前缀,indent=no是为了避免自动缩进干扰008字段的精确格式。
2. 修改XSLT写法,规避相邻纯空白节点
你可以把两个分开的空白<xsl:text>合并成一个:
<xsl:text> </xsl:text> <!-- 直接写8个空格 -->
或者用<xsl:value-of>来输出空白字符串,这样Saxon不会合并相邻的输出:
<xsl:value-of select="' '"/> <xsl:value-of select="' '"/>
因为<xsl:value-of>输出的是字符串值,相邻的value-of结果会被直接拼接,不会触发空白合并逻辑。
3. 检查XSLT中的strip-space设置
如果你的XSLT里有<xsl:strip-space elements="*"/>,这会全局剥离元素内的空白节点,可能影响到008字段的输出。可以修改为只剥离特定元素的空白,或者添加<xsl:preserve-space elements="controlfield"/>来保留目标元素的空白:
<xsl:preserve-space elements="controlfield"/> <xsl:strip-space elements="datafield ..."/> <!-- 只剥离你需要的元素空白 -->
快速验证方法
你可以用你的测试XSLT加上<xsl:output>配置,在本地用Saxon命令行测试:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="xml" indent="no" preserve-space="."/> <xsl:template match="/"> <xsl:text>beginning of a string</xsl:text> <xsl:text> </xsl:text> <xsl:text> </xsl:text> <xsl:text>end of a string</xsl:text> </xsl:template> </xsl:stylesheet>
执行后如果输出包含8个空格,说明配置生效了,再把这个逻辑应用到你的MODS转MARC的XSLT里就行。
内容的提问来源于stack exchange,提问作者Sylvain

