2014-10-06 68 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