2014-10-06 72 views
0

是否有办法获取先前迭代的元素。在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> 

现在我必须选择与状态的所有节点:“接受”的表,然后由栏目组他们其中被查询并且每列只选择具有最近更新时间的两个请求。输出应该是以简单文本形式给出的这些节点的id。例如,对于查询'从表1选择列1'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()) /> 

现在这个工作,但不是我想要的方式,它返回文档在前面的兄弟,但不是以前的迭代的查询文本。是这样的可能吗? 谢谢

+3

输入和请求的输出的例子将是有用的。 - P.S.是否有理由使用'* [local-name()='requests']等等尴尬的表情? – 2014-10-06 18:33:12

+2

@ michael.hor257k有些人会不惜一切代价学习使用命名空间。 – JLRishe 2014-10-07 03:45:03

回答

1

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

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

+0

尊重,这不是一个答案。 – 2014-10-07 09:01:34

+1

我认为第一段是对“这是可能的东西”的回答,基本上说不。第二段是试图让海报编辑问题,让我们比“不”更有帮助,你对“每个”的理解是错误的。 – 2014-10-07 09:41:48

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> 

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

+0

感谢您的解决方案。但我根本没有看到它从不同的表中分离出同名的柱子(例如:从table1中选择column1,从table2中选择column1),因为这个键只提取了列名 – uztrew 2014-10-08 12:54:29

+0

@uztrew我想我在这里丢失了一些东西:如果你想要一个独特的列/表组合,为什么需要解析查询呢?是不是每个独特的查询也是一个独特的列/表组合? – 2014-10-08 14:59:07

+0

空白处怎么样; “从表格1中选择col1”将不会与“从表格1中选择col1”组合在一起。 – uztrew 2014-10-08 16:10:25