如何强制XSLT的collection函数将所有文件视为XSL?
解决Saxon collection函数将非标准扩展名XSL文件识别为二进制的问题
针对你遇到的Saxon解析非标准扩展名(如DTCBS)XSL文件时被识别为base64Binary的问题,有以下几种可行的解决方法:
方法1:在collection URI中指定content-type参数
Saxon的collection函数支持通过content-type参数强制指定文件的解析类型,直接将所有匹配的文件当作XML(XSL本质是XML)处理。修改你的collection调用代码如下:
<xsl:variable name="Collection" select="collection(concat( 'file:///', encode-for-uri(replace($filePath, '\\', '/')), '?select=*.(xsl|dtcbs|xml);recurse=yes;content-type=text/xml' ))" as="node()*"/>
这个参数会覆盖Saxon基于扩展名的类型检测,强制所有符合选择条件的文件以XML格式解析,无需修改原文件的扩展名或添加XML声明。
方法2:用unparsed-text读取后解析为XML节点
如果content-type参数不生效,可以先通过collection获取所有目标文件的URI,再用unparsed-text()读取文件内容,最后通过parse-xml()将文本解析为XML节点:
<!-- 获取所有符合扩展名的文件URI --> <xsl:variable name="targetFiles" select="collection(concat( 'file:///', encode-for-uri(replace($filePath, '\\', '/')), '?select=*;recurse=yes' ))[matches(document-uri(.), '\.(xsl|dtcbs|xml)$', 'i')]" as="xs:anyURI*"/> <!-- 读取并解析每个文件为XML节点 --> <xsl:variable name="Collection" as="node()*"> <xsl:for-each select="$targetFiles"> <!-- 注意:如果文件编码不是UTF-8,需指定对应编码,比如'ISO-8859-1' --> <xsl:sequence select="parse-xml(unparsed-text(., 'UTF-8'))"/> </xsl:for-each> </xsl:variable>
这种方式更灵活,还能处理编码不一致的情况。
方法3:使用Saxon扩展函数treat-as-document
Saxon提供了扩展函数saxon:treat-as-document(),可以将二进制资源强制转换为XML文档处理。需要先声明Saxon命名空间,再修改collection调用:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:saxon="http://saxon.sf.net/" version="2.0"> <!-- 强制将所有collection中的资源当作XML文档解析 --> <xsl:variable name="Collection" select="collection(concat( 'file:///', encode-for-uri(replace($filePath, '\\', '/')), '?select=*.(xsl|dtcbs|xml);recurse=yes' ))!saxon:treat-as-document(.)" as="node()*"/> </xsl:stylesheet>
注意使用此方法需要确保Saxon启用了扩展函数支持(默认通常是开启的)。
内容的提问来源于stack exchange,提问作者Zor
相关产品推荐
相关产品推荐

