如何在Saxon 10.5中配置fn:generate-id生成可预测的唯一ID
可预测fn:generate-id输出的实现方案(Saxon 10.5 Java版)
方案1:Java层自定义生成器(推荐,性能更高,适配所有调用场景)
- 首先实现Saxon提供的
net.sf.saxon.lib.GeneratedIdGenerator接口,仅需重写String generateId(NodeInfo node)方法。你可以基于节点的文档层级路径、节点类型、兄弟节点索引等固定属性拼接生成唯一ID,只要保证同一文档的同一个节点每次生成的字符串一致即可。 - 注册自定义实现到Saxon配置:直接调用
Configuration.setGeneratedIdGenerator(new YourCustomGenerator())将实例绑定到全局配置,也可以通过配置文件设置属性http://saxon.sf.net/feature/generateIdImplementation的值为你实现类的全限定名。
方案2:XSLT层重写内置函数(无需编写Java代码,适配纯XSLT调用场景)
- 在你引入外部XSLT库的主样式表顶层,声明自定义的
fn:generate-id函数,设置override="yes"即可覆盖内置实现,所有内部库的调用都会自动走自定义逻辑,参考实现如下:
<xsl:function name="fn:generate-id" as="xs:string" override="yes"> <xsl:param name="node" as="node()?"/> <xsl:choose> <xsl:when test="empty($node)"> <xsl:sequence select="''"/> </xsl:when> <xsl:otherwise> <!-- Saxon内置path()函数返回的路径默认携带同层级节点索引,天然满足唯一性要求 --> <xsl:sequence select="concat('N', encode-for-uri(path($node)))"/> </xsl:otherwise> </xsl:choose> </xsl:function>
注意:两种实现都必须遵守fn:generate-id的原生语义:同一转换过程中,同一节点多次调用返回值必须相同,不同节点返回值不能重复。如果你的文档存在命名空间,使用path()生成时建议做命名空间前缀的统一处理,避免不同解析上下文前缀不一致导致ID变化。
内容的提问来源于stack exchange,提问作者user1428945
相关产品推荐
相关产品推荐

