如何让XSLT2.0的collection函数将无.xml后缀无声明文件识别为XML
Saxon XSLT强制collection函数识别无XML后缀/无XML声明文件的解决方法
你遇到的报错是Saxon默认的内容识别逻辑导致的:对于没有标准XML后缀、内容也不含XML声明的文件,Saxon的内容嗅探机制会将其判定为二进制文件,返回xs:base64Binary类型的值,和collection函数期望返回的node()类型不匹配,因此抛出XPTY0004类型错误。
以下是两种可直接落地的解决方法:
方法1:使用Saxon专属的collection URI参数(最简方案)
Saxon对collection函数的URI做了扩展支持,你可以直接在集合路径后加contentType=application/xml查询参数,强制所有匹配到的文件按XML格式解析,不需要修改文件后缀或内容:
<!-- 示例:将指定目录下所有文件强制按XML解析 --> <xsl:variable name="xml-collection" select="collection('file:///绝对路径/到/你的文件目录?contentType=application/xml')"/>
该方案兼容Saxon 9.x及以上所有版本,无需修改后续原有处理逻辑。
方法2:使用标准XSLT函数手动解析(无厂商依赖)
如果需要代码兼容其他XSLT处理器,可以通过「读取文本→解析XML」的两步流程实现,完全遵循XSLT 2.0标准规范:
- 先调用
collection获取所有文件的URI引用 - 用
unparsed-text()读取文件内容为字符串 - 用
parse-xml()将字符串转为XML节点
代码示例:
<xsl:template match="/"> <!-- 遍历目标目录下所有匹配的文件 --> <xsl:for-each select="collection('file:///绝对路径/到/你的文件目录?select=*.*') ! document-uri(.)"> <!-- 手动解析为XML文档,第二个参数可根据实际文件编码调整 --> <xsl:variable name="current-doc" select="parse-xml(unparsed-text(., 'utf-8'))"/> <!-- 这里写你原有的XML处理逻辑,直接操作$current-doc即可 --> </xsl:for-each> </xsl:template>
这个方法不受文件后缀、内容是否带XML声明的影响,只要文件内容是格式良好的XML即可正常运行。
内容的提问来源于stack exchange,提问作者Lokesh
相关产品推荐
相关产品推荐

