统一处理分组的同级元素



给定以下 XML 文档

<root>
<a pos="0" total="2"/>
<a pos="1" total="2"/>
<a pos="0" total="3"/>
<a pos="1" total="3"/>
<a pos="2" total="3"/>
<a pos="0" total="4"/>
<a pos="1" total="4"/>
<a pos="2" total="4"/>
<a pos="3" total="4"/>
</root>

我需要将其翻译成

<root>
<group>
<a pos="0" total="2"/>
<a pos="1" total="2"/>
</group>
<group>
<a pos="0" total="3"/>
<a pos="1" total="3"/>
<a pos="2" total="3"/>
</group>
<group>
<a pos="0" total="4"/>
<a pos="1" total="4"/>
<a pos="2" total="4"/>
<a pos="3" total="4"/>
</group>
</root>

使用 XSLT 1.0 样式表。

也就是说,文档中每个<a>元素的@pos属性为0隐式启动一个由它和@total-1 跟随<a>元素组成的组。换句话说,@pos表示元素在相邻元素组中@total从 0 开始的索引(位置)。

我想出了以下样式表,它有效:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes" />
<xsl:template match="/">
<xsl:apply-templates select="root" />
</xsl:template>
<xsl:template match="root">
<xsl:apply-templates select="a[@pos=0]" mode="leader"/>
</xsl:template>
<xsl:template match="a" mode="leader">
<group>
<xsl:apply-templates select="." />
<xsl:apply-templates select="following-sibling::a[position() &lt;= current()/@total - 1]" />
</group>
</xsl:template>
<xsl:template match="a">
<xsl:copy-of select="." />
</xsl:template>
</xsl:stylesheet>

我对我的解决方案的问题是它使这些a[@pos=0]元素"特殊":为了进一步处理潜在组中的每个<a>元素,我必须首先将适当的模板分别应用于"组长"元素,然后应用于组中的其余元素。

换句话说,我非常希望有类似的东西(不正确)

<xsl:template match="a" mode="leader">
<group>
<xsl:apply-templates select=". and following-sibling::a[position() &lt;= current()/@total - 1]" />
</group>
</xsl:template>

这将一次性将我的<xsl:template match="a">模板应用于组中的所有元素。(改写我试图在select表达式中拼写的内容:"选择上下文元素及其以下同级元素匹配......"。

有没有办法在不使用变量和exslt:node-set()等黑客的情况下使用 XSLT 1.0 获得我想要的东西? 也许有比我想出的更好的方法来根据元素计数进行这种分组(这本质上使每个组中的第一个元素变得特别)?


承认这个问题的标题相当薄弱,但我未能提出一个简洁的标题来正确反映我的问题的意义。

你可以做:

<xsl:apply-templates select=". | following-sibling::a[position() &lt;= current()/@total - 1]" />

附言:使用变量或node-set()函数不符合"黑客"的条件。

相关内容

  • 没有找到相关文章

最新更新