0

我有一个包含元素的 XML a,其属性@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 属性是指定键值的表达式;对于与模式匹配的每个节点,都会对表达式进行一次评估。如果结果是一个节点集,那么对于节点集中的每个节点,与模式匹配的节点都有一个指定名称的键,其值为节点集中节点的字符串值;

我需要提供一个函数来@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, '#'))Saxon 会给出相同的错误 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

(不需要特别的顺序)。

4

0 回答 0