XSLT 1.0:基于空格分隔属性的键

时间:2016-03-28 21:00:08

标签: xslt-1.0 exslt

我有一个包含元素a的XML,其属性@ref包含至少一个指针,并且可以包含由空格分隔的任意数量的指针:<a ref="#p1 #p2"/>。在XSLT 1.0样式表中,我需要将模板应用于所有文档,并且仅应用文档中b中引用的那些元素a/@ref

所以,我认为这个想法是定义一个<xsl:key name="k1" match="a" use="my:refs(@ref)"/>,其函数将@ref的值拆分为其成分,然后得到<xsl:template match="b[key('k1', @xml:id)]"/>。如果我正确解释规格:

  

use属性是指定键值的表达式;该   对于与模式匹配的每个节点,将对expression进行一次计算。如果   结果是一个节点集,然后对于节点集中的每个节点,该节点   匹配模式有一个指定名称的键,其值为   节点集中节点的字符串值;

我需要向@use提供一个函数,该函数将node-set的值a/@ref(减去前导'#')作为字符串返回。

我的解决方案是定义<xsl:key name="k1" match="a" use="str:tokenize(@ref, '# ')/><xsl:template match="a[key('k1', @xml:id)">

当我使用Xalan作为处理器时,这给了我想要的结果。然而, Saxon 9.6.0.7抱怨循环键定义。

现在我有点困惑:我的解决方案是否有效? 如果是这样,撒克逊为什么抱怨?还有其他/更好(/真实)的解决方案吗? [见评论]。

编辑:其他问题:如何在XSLT 2.0中获得结果?简单地在键定义中使用tokenize(@ref, '#')是不够的,因为空格,而normalize-space(tokenize(@ref, '#'))撒克逊将给出相同的错误XTDE0640。

谢谢, 达里奥

示例XML:

<root>
    <b xml:id="#p1">P1</b>
    <b xml:id="#p2">P2</b>
    <b xml:id="#pn">Pn</b>
    <a ref="#p2" />
    <a ref="#p1 #pn" />
</root>

输出应为

P1
P2
Pn

(无需特定订单)。

0 个答案:

没有答案