xsl:key 和 key() 是 XSLT 中预建哈希表式索引机制,通过“一次建表、多次查表”提升重复查找性能;xsl:key 在顶层声明索引规则,key() 函数依名查键值节点组,适用于关联、分组、去重等高效场景。
xsl:key 和 key() 是 XSLT 中用于构建和查询索引的核心机制,本质是“预建哈希表”,让重复查找某个字段(如 ID、类别、状态)时无需遍历全树,大幅提升性能。关键不在语法多复杂,而在理解它“一次建表、多次查表”的设计逻辑。
它不执行查找,只定义“按什么条件把哪些节点归为一组”。必须写在顶层( 或 内,不能嵌套在模板中)。
key() 函数靠它引用例如,给所有 按 category 属性建立索引:
key($name, $key-value) 在任意上下文调用,返回所有 match 节点中、use 表达式结果等于 $key-value 的节点集合(保持原文档顺序)。
xsl:key 中定义的 name 字符串(加引号)'fiction')、变量($cat)、或表达式(current()/@ref) 遍历,或用 count()、position() 等函数处理比如,在某处列出所有 category="tech" 的书:
真正体现价值的地方,是避免 N×M 嵌套循环。
和 ,用 key
('products', @product-id) 直接拉出对应商品,不用 //product[@id = current()/@product-id] 全局扫描xsl:key 按城市分组客户,再用 key('customers', 'shanghai') 拿到全部上海客户,count() 一下就是人数generate-id() 判断是否首见(generate-id() = generate-id(key('by-name', @name)[1])),比 not(@name = preceding-sibling::*/@name) 快得多看似简单,但几个细节决定是否真高效:
xsl:key 是全局声明,但索引构建发生在整个输入文档加载后、模板匹配前 —— 所以它对整个文档生效,不随当前模板变化use 表达式结果)自动转为字符串;若需多字段组合键,用 concat(a, '|', b),确保分隔符不会出现在原始值中key() 只能查当前文档(document('') 除外);XSLT 2.0+ 支持跨文档索引(用 key('k', 'v', $doc))