2016-03-17 95 views
0

XML输入:XSLT选择最低值的ID匹配

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

我想每列名=“订购”具有相同的ID展示在<grt>中标记了列名'FirstAction'的最低值。如果列名'订单'不重复,则在<grt>中显示标记当前<record>标记中'FirstAction'的值。 基本上,如果相同的订单号码重复自己采取最低的第一个行动号码,如果不是,那么只需要从第一个行动节点的值。 我似乎无法使其工作。

我的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

为什么最后一条记录,没有订单/任务值,从结果中排除? –

回答

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