XSLT调用fn:doc-available()遇多序列参数报错的解决咨询
问题分析与解决方案
一、错误根源
fn:doc-available()要求第一个参数必须是单个字符串(或可转换为单个字符串的节点),当你匹配到多个dmFile节点时,直接提取@href会返回一个字符串序列,这就触发了"A sequence of more than one item is not allowed"错误。你之前添加[1]无效,大概率是位置加错了——必须先筛选出单个dmFile节点,再提取它的@href。
二、正确的过滤方法
1. 精准匹配单个节点并提取href
假设你要匹配的目标dmIndex值为'target-id',正确写法如下:
<!-- 先加载dmIndex.xml到变量,避免重复读取 --> <xsl:variable name="dm-index-doc" select="document('dmIndex.xml')" /> <!-- 筛选第一个匹配@dmIndex的dmFile,再取它的@href --> <xsl:variable name="target-href" select="$dm-index-doc//dmFile[@dmIndex='target-id'][1]/@href" /> <!-- 传入doc-available()检测 --> <xsl:if test="doc-available($target-href)"> <!-- 文档存在时的处理逻辑 --> <xsl:copy-of select="document($target-href)" /> </xsl:if>
这里的[1]必须加在dmFile[@dmIndex='target-id']之后,确保只选中第一个匹配的节点,再提取其@href,保证传入doc-available()的是单个字符串(或空值)。
2. 处理@dmIndex为空的场景
如果要匹配@dmIndex为空的节点,分两种情况:
- 匹配属性存在但为空的节点:
<xsl:variable name="empty-index-href" select="$dm-index-doc//dmFile[@dmIndex=''][1]/@href" /> - 匹配属性不存在的节点:
<xsl:variable name="no-index-href" select="$dm-index-doc//dmFile[not(@dmIndex)][1]/@href" />
3. 避免错误的[1]位置
错误示例(你可能之前这么写过):
<!-- 错误:先提取所有匹配节点的@href,再取第一个 --> <xsl:variable name="wrong-href" select="$dm-index-doc//dmFile[@dmIndex='target-id']/@href[1]" />
虽然这个写法也能得到单个字符串,但逻辑上不够严谨——如果节点存在但@href为空,会返回空序列。先筛选节点再取属性的方式更可靠。
三、更优的文档存在性检测方案
1. 批量检测+性能优化
如果需要检测多个dmFile对应的文档,先预加载dmIndex.xml并批量处理,避免重复IO:
<xsl:variable name="dm-index-doc" select="document('dmIndex.xml')" /> <!-- 筛选所有目标dmFile节点 --> <xsl:variable name="target-files" select="$dm-index-doc//dmFile[@dmIndex='target-id']" /> <xsl:for-each select="$target-files"> <xsl:variable name="current-href" select="@href" /> <!-- 先判断href非空,再检测文档存在性 --> <xsl:if test="string($current-href) != '' and doc-available($current-href)"> <!-- 处理当前存在的文档 --> <xsl:element name="valid-document"> <xsl:value-of select="$current-href" /> </xsl:element> </xsl:if> </xsl:for-each>
2. 用key提升大文档的匹配效率
如果dmIndex.xml体积较大,多次使用//dmFile[@dmIndex='xxx']会影响性能,可定义key加速查找:
<!-- 定义key,按@dmIndex分组匹配dmFile节点 --> <xsl:key name="dm-file-by-index" match="dmFile" use="@dmIndex" /> <xsl:variable name="dm-index-doc" select="document('dmIndex.xml')" /> <!-- 通过key快速获取所有匹配的节点 --> <xsl:variable name="target-files" select="key('dm-file-by-index', 'target-id', $dm-index-doc)" />
3. 处理空href的边界情况
如果dmFile的@href可能为空,必须先过滤,避免传入空字符串给doc-available():
<xsl:if test="string(@href) != ''"> <xsl:if test="doc-available(@href)"> <!-- 处理逻辑 --> </xsl:if> </xsl:if>
内容的提问来源于stack exchange,提问作者Caroline
相关产品推荐
相关产品推荐

