在xslt 1.0中获取上一次迭代的元素

时间:2014-10-06 18:07:02

标签: xslt iteration xslt-1.0

是否可以获取上一次迭代的元素。

我有以下XML文档(缩写为更好的概述):

    <requests>
             <request>
                     <id>514</id>
                     <status>accepted</status>
                     <updated>"2013-10-07T12:00:51.508"</updated>
                     <query>
                        <![CDATA[Select column1 from table1]]>
                     </query>
             </request>
             <request>
                     <id>22</id>
                     <status>rejected</status>
                     <updated>"2012-11-07T12:00:51.508"</updated>
                     <query>
                        <![CDATA[Select column3 from table2]]>
                     </query>
             </request>
             <request>
                     <id>7523</id>
                     <status>accepted</status>
                     <updated>"2012-01-07T02:00:52.508"</updated>
                     <query>
                        <![CDATA[Select column8 from table3]]>
                     </query>
             </request>
             <request>
                     <id>84</id>
                     <status>accepted</status>
                     <updated>"2000-12-07T12:00:51.1"</updated>
                     <query>
                        <![CDATA[Select column1 from table1]]>
                     </query>
             </request>
             <request>
                     <id>999</id>
                     <status>accepted</status>
                     <updated>"2006-12-07T12:00:51.1"</updated>
                     <query>
                        <![CDATA[Select column1 from table1]]>
                     </query>
             </request>
                 .
                 .
                 .
     </requests>

现在我必须选择状态为的所有节点:&#34;接受&#34;按表对它们进行分组,然后按查询的列进行分组,每列只选择两个具有最新更新时间的请求。输出应该是以简单文本形式给出的这些节点的ID。例如,对于查询&#39;从表1中选择column1&#39;应选择514和999进行输出,而不选择84。我已经阅读了有关muenchian方法但我无法将其应用于已解析的文本(在本例中为查询中的文本)。 这就是为什么我试图找出从前一次迭代中获取信息的方法,这样我就可以按给定的标准对节点进行排序,并找到我要查找的id。

例如:

<xsl:for-each select="*[local-name()='requests']/*[local-name='request'][@status='accepted']" >
  <xsl:sort select="string(*[local-name()='query']/text())" order="text" data-type="number" />
  <xsl:sort select="@pdated" order="descending" data-type="number" />
  <xsl:value-of select="string(preceding-sibling::*[1]/*[local-name()='query']/text()) />

现在这可行,但不是我想要的方式,它返回文档中的前一个兄弟,但不返回上一次迭代的查询文本。这样的事情可能吗? 感谢

2 个答案:

答案 0 :(得分:1)

XSLT是一种声明性语言,虽然for-each可能看起来像一个过程for循环,但在XSLT 1.0或2.0规范中没有这个概念。因此previous iteration的概念也不存在。只有带有xsl:iterate的XSLT 3.0提供了这些内容,以允许处理非常大的文档而无需将完整的文档树加载到内存中。

使用XSLT 1.0,您需要使用不同的方法,您需要发布您要处理的输入样本的结构以及您想要创建的相应结果,以便我们帮助您使用具体的代码。

答案 1 :(得分:0)

  

我已经读过有关muenchian方法的内容,但我无法将其应用于   解析文本(在本例中为查询中的文本)。

这是基于解析文本应用Muenchian分组的方法 - 在这种情况下,列名称为:

<?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" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>

<xsl:key name="req" match="request[status='accepted']" use="substring-before(substring-after(query ,'Select '), ' from')" />

<xsl:template match="/">
    <root>
        <xsl:for-each select="requests/request[status='accepted'][count(. | key('req', substring-before(substring-after(query ,'Select '), ' from'))[1]) = 1]">
            <group>
                <xsl:value-of select="query"/>
            </group>
        </xsl:for-each>
    </root>
</xsl:template>

</xsl:stylesheet>

应用于您的示例输入,这将导致:

<?xml version="1.0" encoding="UTF-8"?>
<root>
  <group>Select column1 from table1</group>
  <group>Select column8 from table3</group>
</root>

现在您只需要按更新时间对组成员进行排序并输出前两个。