如何在XSLT 2.0中检测图片文件是否存在?解决file:exists()函数处理非XML文件的UTF-8错误
解决Saxon中
file:exists()检测图片文件时的UTF-8编码错误问题 这个问题的根源在于Saxon的file:exists()函数在处理二进制文件(比如jpg、png这类图片)时,会尝试以UTF-8编码读取文件内容做验证——但图片是二进制格式,字节序列自然不符合UTF-8规范,所以抛出了Invalid byte 1 of 1-byte UTF-8 sequence错误。而XML文件本身是UTF-8编码的文本文件,因此不会触发这个问题。
既然你用的是Saxon-PE,它支持调用Java扩展方法,我们可以换个思路:直接用Java的java.io.File类来检查文件是否存在。这个方法只会验证文件系统中是否存在对应路径的文件,完全不会读取或解析文件内容,完美适配二进制文件场景。
修改后的完整代码
首先需要在XSLT的根元素里声明Java扩展的命名空间:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:file="http://saxon.sf.net/file" xmlns:java="http://saxon.sf.net/java-type" version="2.0">
然后修改你的模板逻辑,针对<image>元素使用Java的文件检查方法:
<xsl:template match="*[@href]"> <xsl:variable name="resPath" select="resolve-uri( @href, base-uri() )"/> <xsl:variable name="check"> <xsl:choose> <xsl:when test="self::image"> <!-- 使用Java File类检查文件存在,避免解析二进制内容 --> <xsl:variable name="uriObj" select="java:java.net.URI.new($resPath)"/> <xsl:variable name="fileObj" select="java:java.io.File.new($uriObj)"/> <xsl:value-of select="java:exists($fileObj)"/> </xsl:when> <xsl:otherwise> <!-- 原逻辑保留,处理XML文件 --> <xsl:value-of select="file:exists($resPath)"/> </xsl:otherwise> </xsl:choose> </xsl:variable> <xsl:choose> <xsl:when test="$check = true()"> <li> <span><xsl:value-of select="@href"/></span><span style="padding-left:5px">Good</span> </li> </xsl:when> <xsl:otherwise> <li style="background-color:#ffcccc" > <span><xsl:value-of select="@href"/></span><span style="padding-left:5px">Bad</span> </li> </xsl:otherwise> </xsl:choose> </xsl:template>
为什么这个方法有效?
java.io.File.exists()是纯粹的文件系统检查操作,它只关心指定路径下是否存在对应的文件或目录,不会对文件内容做任何编码解析操作。不管是图片、视频还是其他二进制文件,都能准确返回存在状态,不会触发UTF-8相关的错误。
另外,我们通过java.net.URI来构造File对象,能更好地处理包含特殊字符的路径(比如空格、非ASCII字符),避免直接使用字符串路径可能出现的编码问题。
内容的提问来源于stack exchange,提问作者user3618078
相关产品推荐
相关产品推荐

