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

Теперь я должен выбрать все узлы со статусом: «принято» группировать их по столу, а затем в колонке, которая запрашивается и для каждого столбца выбирают только два запроса с самым последним временем обновления. Вывод должен быть идентификатором этого узла, заданным как простой текст. Например, для запроса «Выбрать столбец1 из таблицы 1» следует выбрать 514 и 999 для вывода, тогда как 84 нет. Я прочитал о методе muenchian, но я не смог применить его в анализируемом тексте (в этом случае текст в запросе). Вот почему я попытался выяснить способ получения информации из предыдущей итерации, чтобы я мог сортировать узлы по заданным критериям и находить идентификатор, который я ищу.

Например:

<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']' и т. Д.? –

+2

@ michael.hor257k Некоторые люди избегают научиться использовать пространства имен любой ценой. – JLRishe

ответ

1

XSLT является декларативным языком и в то время как for-each может выглядеть процедурного for цикла не существует понятие, что в XSLT 1.0 или 2.0. Поэтому понятие previous iteration не существует. Только XSLT 3.0 с xsl:iterate обеспечивает что-то вдоль этих строк, чтобы разрешить обработку очень больших документов без загрузки полного дерева документов в память.

С XSLT 1.0 вам нужно будет использовать другой подход, вам нужно будет опубликовать структуру входных выборок, которые вы хотите обработать, и соответствующий результат, который вы хотите создать, чтобы мы могли помочь с конкретным кодом.

+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> 

Теперь вам нужно просто отсортировать членов группы по времени обновления и вывести первые два.

+0

Спасибо за это решение.Но я просто не вижу, чтобы он разделял колоны с тем же именем из разных таблиц (например: выберите столбец1 из таблицы1 и выберите столбец1 из таблицы2), потому что ключ только извлекает имя столбца – uztrew

+0

@uztrew. По-моему, я чего-то не хватает : если вам нужна уникальная комбинация столбцов/таблиц, зачем нужно разбирать запрос вообще? Не является ли каждый уникальный запрос уникальной комбинацией столбцов и таблиц? –

+0

Как насчет пробелов; «select col1 from table1» не будет группироваться вместе с «select col1 from table1». – uztrew

Смежные вопросы