2016-03-17 5 views
0

XML Вход:XSLT Выберите наименьшее значение узла на основе матча ид

<Root> 


<output> 
    <queries> 
     <query name="Test"> 
      <parameters> 
       <parameter>298674,298673,298675,298676</parameter> 
      </parameters> 
      <queryResults> 
       <record id="1"> 
        <column name="Order">272334</column> 
        <column name="Task">272093</column> 
        <column name="FirstAction">2709305</column>      
       </record> 
       <record id="2"> 
        <column name="Order">272334</column> 
        <column name="Task">272093</column> 
        <column name="FirstAction">2709301</column> 
       </record> 
       <record id="3"> 
        <column name="Order">272334</column> 
        <column name="Task">272093</column> 
        <column name="FirstAction">2709306</column> 
       </record> 
       <record id="4"> 
        <column name="Order">268997</column> 
        <column name="Task">268756</column> 
        <column name="FirstAction">2709307</column> 
       </record> 
       <record id="5"> 
        <column name="Order"/> 
        <column name="Task"/> 
        <column name="FirstAction">2709307</column> 
       </record> 
      </queryResults> 
     </query> 
    </queries> 
</output> 
</Root> 

Желаемая Выход:

<Tag1> 
<Tag2> 
    <parameters> 
     <order id="272334"/> 
     <order id="268997"/> 
     <task id="272093"> 
      <grt> 
       <action id="2709301"/> 
      </grt> 
     </task> 
     <task id="268756"> 
      <grt> 
       <action id="2709307"/> 
      </grt> 
     </task> 
    </parameters> 
</Tag2> 
</Tag1> 

Я хочу, чтобы для каждого имени столбца = «Order», который имеет тот же идентификатор, чтобы показать в <grt> отметьте самое нижнее значение имени столбца «FirstAction». Если имя столбца «Заказ» не повторяется, то в <grt> отметьте значение «FirstAction» с текущего тега <record>. В принципе, если один и тот же номер заказа повторяется, возьмите младший номер первого действия, если нет, то просто возьмите значение из первого узла действия. Я не могу заставить работать.

В настоящее время XSL показывает все отдельные значения для заказа без повторения, но не знает, как это сделать для узла FirstAction.

Мой XSL:

<xsl:template match="/"> 
    <Tag1> 
     <Tag2> 
      <parameters> 
       <xsl:for-each select="//record/column[@name='Order'][not(.=preceding::*)]"> 
        <order> 
         <xsl:attribute name="id"><xsl:value-of select="."/></xsl:attribute> 
        </order> 
       </xsl:for-each> 
       <xsl:for-each select="//record/column[@name='Task'][not(.=preceding::*)]"> 
        <task> 
         <xsl:attribute name="id"><xsl:value-of select="."/></xsl:attribute> 
         <grt> 
          <action> 
           <xsl:attribute name="id"><xsl:value-of select="current()/@column[@name='FirstAction']"/></xsl:attribute> 
          </action> 
         </grt> 
        </task> 
       </xsl:for-each> 

      </parameters> 
     </Tag2> 
    </Tag1> 
</xsl:template> 
</xsl:stylesheet> 

Большое спасибо!

+0

Вы можете использовать XSLT 2.0? –

+0

Нет :(только 1.0 к сожалению – user3529643

+0

Почему последняя запись без значений Order/task исключена из результата? –

ответ

2

Во-первых, я предлагаю вам использовать Muenchian method для группировки ваших записей - и делать это только один раз.

Затем используйте один и тот же ключ, чтобы получить записи в текущей группе, сортировать их по значению FirstAction, и получить первую запись в отсортированном группе:

XSLT 1,0

<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:key name="record-by-order" match="record" use="column[@name='Order']" /> 

<xsl:template match="/Root"> 
    <xsl:variable name="unique-orders" select="//record[count(. | key('record-by-order', column[@name='Order'])[1]) = 1]"/> 
    <Tag1> 
     <Tag2> 
      <parameters> 
       <xsl:for-each select="$unique-orders"> 
        <order id="{column[@name='Order']}"/> 
       </xsl:for-each> 
       <xsl:for-each select="$unique-orders"> 
        <task id="{column[@name='Task']}"> 
         <xsl:for-each select="key('record-by-order', column[@name='Order'])"> 
          <xsl:sort select="column[@name='FirstAction']" data-type="number" order="ascending"/> 
          <xsl:if test="position()=1"> 
           <grt> 
            <action id="{column[@name='FirstAction']}"/> 
           </grt> 
          </xsl:if> 
         </xsl:for-each> 
        </task> 
       </xsl:for-each> 
      </parameters> 
     </Tag2> 
    </Tag1> 
</xsl:template> 

</xsl:stylesheet> 

Применительно к введенному, то результат будет:

<?xml version="1.0" encoding="UTF-8"?> 
<Tag1> 
    <Tag2> 
     <parameters> 
     <order id="272334"/> 
     <order id="268997"/> 
     <order id=""/> 
     <task id="272093"> 
      <grt> 
       <action id="2709301"/> 
      </grt> 
     </task> 
     <task id="268756"> 
      <grt> 
       <action id="2709307"/> 
      </grt> 
     </task> 
     <task id=""> 
      <grt> 
       <action id="2709307"/> 
      </grt> 
     </task> 
     </parameters> 
    </Tag2> 
</Tag1> 

Примечание:

Для исключения записей не Order значения, попробуйте:

<xsl:variable name="unique-orders" select="//record[string(column[@name='Order'])][count(. | key('record-by-order', column[@name='Order'])[1]) = 1]"/> 
+0

ВЫ, сэр, спасатели жизни! Большое вам спасибо. Я изучу этот пример и логику, поэтому я буду знать в будущем. – user3529643

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