2016-12-07 6 views
1

я должен перебрать Main/MainLines/MainLine и получить сумму (количество) for-each - Item/ItemNo .The выхода должен быть только один MainLine элемента для каждого ItemNo .The, как я делаю, я получаю повторен.XSLT: Перебор и получить значение атрибута уникального

Входной

<Main Company="ABC" MainNo="213211" > 
    <MainLines> 
    <MainLine Quantity="2" Node="9999"> 
     <Item ItemNo="123123" Class="NEW"/> 
    </MainLine> 
    <MainLine Quantity="1" Node="9999"> 
     <Item ItemNo="123123" Class="NEW"/> 
    </MainLine> 
    <MainLine Quantity="3" Node="9999"> 
     <Item ItemNo="123123" Class="NEW"/> 
    </MainLine> 
    <MainLine Quantity="2" Node="9999"> 
     <Item ItemNo="22222" Class="NEW"/> 
    </MainLine> 
    </MainLines> 
</Main> 

Выход

<Main Company="ABC" MainNo="213211" Reason="NewFile"> 
    <MainLines> 
    <MainLine ExtnQuantity="6"> 
     <MainLine Quantity="2" Node="9999"> 
     <Item ItemNo="123123" Class="NEW" /> 
     </MainLine> 
    </MainLine> 
    <MainLine ExtnQuantity="6"> 
     <MainLine Quantity="1" Node="9999"> 
     <Item ItemNo="123123" Class="NEW" /> 
     </MainLine> 
    </MainLine> 
    <MainLine ExtnQuantity="6"> 
     <MainLine Quantity="3" Node="9999"> 
     <Item ItemNo="123123" Class="NEW" /> 
     </MainLine> 
    </MainLine> 
    <MainLine ExtnQuantity="2"> 
     <MainLine Quantity="2" Node="9999"> 
     <Item ItemNo="22222" Class="NEW" /> 
     </MainLine> 
    </MainLine> 
    </MainLines> 
</Main> 

XSL

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:output method="xml" indent="yes"/> 
    <xsl:template match="/"> 
    <Main> 
    <xsl:copy-of select="Main/@*"/> 
    <xsl:attribute name="Reason"> 
     <xsl:value-of select="'NewFile'"/> 
    </xsl:attribute> 
    <MainLines> 

     <xsl:for-each select="Main/MainLines/MainLine"> 
     <MainLine> 
      <xsl:variable name="ITEM_ID"> 
      <xsl:value-of select="Item/@ItemNo"/> 
      </xsl:variable> 

      <xsl:attribute name="ExtnQuantity"> 
      <xsl:value-of select="sum(../MainLine[Item/@ItemNo = $ITEM_ID]/@Quantity)"/> 
      </xsl:attribute> 
      <xsl:copy-of select="."/> 
     </MainLine> 
     </xsl:for-each> 

    </MainLines> 
    </Main> 
    </xsl:template> 
</xsl:stylesheet> 

Ожидаемый результат

<Main Company="ABC" MainNo="213211" Reason="NewFile"> 
    <MainLines> 
    <MainLine ExtnQuantity="6"> 
     <MainLine Quantity="2" Node="9999"> 
     <Item ItemNo="123123" Class="NEW" /> 
     </MainLine> 
    </MainLine> 
    <MainLine ExtnQuantity="2"> 
     <MainLine Quantity="2" Node="9999"> 
     <Item ItemNo="22222" Class="NEW" /> 
     </MainLine> 
    </MainLine> 
    </MainLines> 
</Main> 

ответ

1

Задача Muenchian grouping. Вы можете решить эту проблему путем повторения только уникальных значений ItemNo. Вот адаптированная версия вашей таблицы стилей:

Обратите внимание, что я переместил элемент <MainLines> в свой собственный шаблон, чтобы уменьшить вложенность. Кроме того, вы можете добавлять атрибуты непосредственно к элементу, вам не нужно <xsl:attribute>.

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:output method="xml" indent="yes" /> 

    <!-- Define key --> 
    <xsl:key name="ItemNoKey" match="MainLine/Item" use="@ItemNo" /> 

    <xsl:template match="/Main"> 
    <Main Reason="NewFile"> 
     <xsl:copy-of select="@*"/> 
     <xsl:apply-templates select="MainLines"/> 
    </Main> 
    </xsl:template> 

    <xsl:template match="MainLines"> 
    <MainLines> 

     <!-- For each first MainLine with a given ItemNo --> 
     <xsl:for-each select="MainLine[count(Item | key('ItemNoKey', Item/@ItemNo)[1]) = 1]"> 
     <xsl:variable name="CurrentItemNo" select="Item/@ItemNo"/> 

     <!-- Print MainLine with quantity sum --> 
     <MainLine ExtnQuantity="{sum(../MainLine[Item/@ItemNo = $CurrentItemNo]/@Quantity)}"> 

      <!-- Copy the selected MainLine element --> 
      <xsl:copy-of select="."/> 
     </MainLine> 
     </xsl:for-each> 

    </MainLines> 
    </xsl:template> 
</xsl:stylesheet>