的自定义格式
是否可以为
定义自定义格式?
我有这样的情况:需要标准的基于字母的格式,但字母表中的某些字符是被禁止的(奇怪的要求,但这是客户所要求的)。例如,不能使用字母 i
,因此当使用
时,我应该得到序列:a, b, c, d, e, f , g, h, j, k, ..., aa, ab, ..., ah, aj, ...
该项目使用 XSLT 2.0 和 Saxon,因此如果存在特定于 Saxon 的解决方案,即好的。
XSLT 2.0 是否提供定义自定义格式序列的功能? Saxon 是否提供注册自定义序列以与
一起使用的功能?
Is it possible to define a custom format for <xsl:number>
?
I have the case where a standard alpha-based format is desired, but certain characters in the alphabet are forbidden (strange requirement, but it is what the client requires). For example, the letter i
cannot be used, so when using <xsl:number>
I should get the sequence: a, b, c, d, e, f, g, h, j, k, ..., aa, ab, ..., ah, aj, ...
The project is using XSLT 2.0 and Saxon, so if a solution exists that is specific to Saxon, that is okay.
Does XSLT 2.0 provide the capability to define a custom format sequence? Does Saxon provide a capability to register a custom sequence for use with <xsl:number>
?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
XSLT 2.0 为
xsl:number
提供了format
属性,您可以通过该属性使用格式标记aa
。计算出的数字取决于value
属性内计算的表达式,并将根据format
进行格式化。鉴于此,您可以考虑首先评估正确的数字序列,排除那些与特定字母匹配的数字。
例如,以下指令:
将打印(注意排除了
i
):if
$sequence
计算结果为(注意跳过了9
):注意,如果您有 12 个元素,您的表达式应该能够跳过不需要的数字(
i
为 9)并增加 1 个元素。位置为 12 的最后一个元素应该有相应的数字 13。所以你需要的只是计算所需序列的算法;这绝对取决于您的输入文档。
参考文献:XSLT 2.0 建议
XSLT 2.0 provides the
format
attribute forxsl:number
by which you can use the format tokenaa
for example. The computed number depends by the expression evaluated insidevalue
attribute and will be formatted accordingly toformat
.Given this, you can think of first evaluating the correct sequence of numbers excluding those that will match for a particular letter.
For instance, the following instruction:
will print (notice
i
excluded):if
$sequence
evaluates to (notice9
skipped):Notice that if you have 12 elements your expression should be able to skip the unwanted number (9 for
i
) and increase the following of one. The last element with position 12, should have corresponding number 13.So what you need, is just the algorithm that computes the wanted sequence; which depends definitely from your input document.
References: XSLT 2.0 Rec.
您可以通过编写接口 net.sf.saxon.lib.Numberer 的实现来自定义 Saxon 中 xsl:number 的输出:您可能希望将其设为 net.sf.saxon.expr.number.Numberer_en 的子类。您需要研究源代码并找出需要覆盖的内容。
在 Saxon PE/EE 中,您可以在 Saxon 配置文件中注册用于给定语言的编号器。对于 Saxon HE,它需要更多的工作:您必须实现 LocalizerFactory 接口并使用配置注册您的 LocalizerFactory。
You can customize the output of xsl:number in Saxon by writing an implementation of the interface net.sf.saxon.lib.Numberer: probably you will want to make this a subclass of net.sf.saxon.expr.number.Numberer_en. You'll need to study the source code and work out what needs overriding.
In Saxon PE/EE you can register the Numberer to be used for a given language in the Saxon configuration file. For Saxon HE it requires a bit more work: you have to implement the interface LocalizerFactory and register your LocalizerFactory with the Configuration.
编辑:存在一个替代的、更通用的解决方案,并作为单独的答案发布。我留下这个答案,因为它对某些人来说可能仍然有价值。
我喜欢@empo的想法(我对其进行了修改),但我认为可能很难找到可行的解决方案。需要一个聪明的算法/方程来根据原始序列得出正确的序列号,以避免获得不包含禁止字符的标签。这时,我忘记了这样的算法。
我想出的一种方法是创建自己的函数,而不是使用
。本质上,我们正在处理一个基数 23 的集合,即字母a
到z
,但不包括字符i
、l< /code> 和
o
。我想出的函数最多只能达到zz
,但这应该足以满足需要(提供最多 552 个项目的标签)。当我执行上面的代码时,我得到以下输出:
如果 XSLT 能够提供定义与
一起使用的自定义字符序列的功能,那就太好了。似乎这样的功能可以概括
而不依赖于自定义扩展,我不知道是否有任何 XSLT 引擎提供
代码>.EDIT: An alternate, more general, solution exists and is posted as a separate answer. I'm leaving this answer since it still may be of value to some.
I like @empo's thinking (I mod'ed it up), but I think it may be hard to get a working solution. A clever algorithm/equation is required to come up with the correct sequence number based on the raw sequence to avoid getting a label that does not contain the forbidden characters. At this time, such an algorithm escapes me.
One method I came up with is to create my own function, and not use
<xsl:number>
. In essence, we are dealing with a base 23 set, the lettersa
toz
, but excluding the charactersi
,l
, ando
. The function I came up with only goes up tozz
, but that should be sufficient for what is needed (provides labelling up to 552 items).When I execute the above, I get the following output:
It would be nice of XSLT provided the capability to define a custom character sequence for use with
<xsl:number>
. Seems like such a capability would generalize<xsl:number>
w/o relying on custom extensions, which I do not know if any XSLT engine provides for<xsl:number>
.在发布我对问题的原始解决方案后,我提出了以下更通用的解决方案。该解决方案是纯 XSLT,并且在基础上仍然使用
,因此应该适用于任何格式类型。I came up with the following, more generalized solution, after posting my original solution to the problem. The solution is pure XSLT and at the base, still uses
<xsl:number>
, so should be applicable to any format type.