2017-02-15 8 views
0

Для каждого узла <LineDetail>, который имеет такое же значение <CtryCd> и заполняет 1 <LineDetail> суммированием <Amt>. Но, я также должен проверить узел <SI> и <TI>. Выходной тег суммирования будет основываться на узлах <SI> и <TI> . <Amt1> будет генерировать, если значение <SI> и <TI> являются ложными, тогда как <Amt2> будет генерировать, если значение <SI> истинно и <TI> является ложным. Я создал XSLT и уже получил суммирование. Но на моем выходе все еще что-то не хватает.Группировка переменных в XSLT 2.0

Это пример XML:

<Record> 
<Data> 
    <Process> 
     <Header> 
      <ID>22-BBB</ID> 
      <Date>2017-02-14</Date> 
      <ContactName>Abegail</ContactName> 
      <!-- some other elements --> 
     </Header> 
     <Detail> 
      <ID>22-CCC</ID> 
      <RequestedDate>2017-02-14</RequestedDate> 
      <!-- some other elements --> 
      <LineDetail> 
       <CtryCd>AF</CtryCd> 
       <SI>false</SI> 
       <TI>false</TI> 
       <Amt>11.11</Amt> 
      </LineDetail> 
      <LineDetail> 
       <CtryCd>SE</CtryCd> 
       <SI>true</SI> 
       <TI>false</TI> 
       <Amt>22.22</Amt> 
      </LineDetail> 
      <LineDetail> 
       <CtryCd>AF</CtryCd> 
       <SI>false</SI> 
       <TI>false</TI> 
       <Amt>33.33</Amt> 
      </LineDetail> 
      <LineDetail> 
       <CtryCd>AF</CtryCd> 
       <SI>true</SI> 
       <TI>false</TI> 
       <Amt>55.55</Amt> 
      </LineDetail>  
     </Detail> 
    </Process> 
</Data> 
</Record> 

сгенерированным:

<Record> 
<Data> 
    <Process> 
     <Header> 
      <ID>22-BBB</ID> 
      <Date>2017-02-14</Date> 
      <ContactName>Abegail</ContactName> 
      <!-- some other elements --> 
     </Header> 
     <Detail> 
      <LineDetail> 
       <CtryCd>AF</CtryCd> 
       <Amt1>99.99</Amt1> 
      </LineDetail> 
     </Detail> 
     <Detail> 
      <LineDetail> 
       <C<Amt2>22.22</Amt2> 
      </LineDetail> 
     </Detail> 
    </Process> 
</Data> 
</Record> 

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

<Record> 
<Data> 
    <Process> 
     <Header> 
      <ID>22-BBB</ID> 
      <Date>2017-02-14</Date> 
      <ContactName>Abegail</ContactName> 
      <!-- some other elements --> 
     </Header> 
     <Detail> 
      <ID>22-CCC</ID> 
      <RequestedDate>2017-02-14</RequestedDate> 
      <!-- some other elements --> 
      <LineDetail> 
       <CtryCd>AF</CtryCd> 
       <Amt1>44.44</<Amt1> 
       <Amt2>55.55</Amt2> 
      </LineDetail> 
      <LineDetail> 
       <CtryCd>SE</CtryCd> 
       <Amt1>0</<Amt1> 
       <Amt2>22.22</Amt2> 
      </LineDetail>   
     </Detail> 
    </Process> 
</Data> 
</Record> 

XSLT:

<xsl:stylesheet version="2.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="CtryCd" match="LineDetail" use="CtryCd"/> 
<!-- identity transform --> 
<xsl:template match="@*|node()"> 
    <xsl:copy> 
     <xsl:apply-templates select="@*|node()"/> 
    </xsl:copy> 
</xsl:template> 
<xsl:template match="Detail"> 
    <xsl:for-each-group select="LineDetail" group-by="CtryCd"> 
     <Detail> 
      <LineDetail> 
       <CtryCd> 
        <xsl:value-of select="CtryCd"/> 
       </CtryCd> 
       <xsl:if test="lower-case(SI)='false' and lower-case(TI)='false'"> 
        <Amt1> 
         <xsl:value-of select="sum(current-group()/Amt)"/> 
        </Amt1> 
       <xsl:if test="lower-case(SI)='true' and lower-case(TI)='false'"> 
        <Amt2> 
         <xsl:value-of select="sum(current-group()/Amt)"/> 
        </Amt2> 
       </xsl:if> 
       </xsl:if> 
       <xsl:if test="lower-case(SI)='true' and lower-case(TI)='false'"> 
        <Amt2> 
         <xsl:value-of select="sum(current-group()/Amt)"/> 
        </Amt2> 
       </xsl:if> 
      </LineDetail> 
     </Detail> 
    </xsl:for-each-group> 
</xsl:template> 
</xsl:stylesheet> 

ответ

1

Вы ток, если условие будет проверять только первый элемент в группе. Вам действительно нужно, чтобы он был частью фактического оператора суммы, как условие для каждого узла в группе.

<Amt1> 
    <xsl:value-of select="sum(current-group()[lower-case(SI)='false' and lower-case(TI)='false']/Amt)"/> 
</Amt1> 

Вы бы тогда аналогичное утверждение для Amt2, тестирование для "истинного" и "ложного"

Попробуйте XSLT

<xsl:stylesheet version="2.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="CtryCd" match="LineDetail" use="CtryCd"/> 

<!-- identity transform --> 
<xsl:template match="@*|node()"> 
    <xsl:copy> 
     <xsl:apply-templates select="@*|node()"/> 
    </xsl:copy> 
</xsl:template> 

<xsl:template match="Detail"> 
    <xsl:for-each-group select="LineDetail" group-by="CtryCd"> 
     <Detail> 
      <LineDetail> 
       <CtryCd> 
        <xsl:value-of select="CtryCd"/> 
       </CtryCd> 
       <Amt1> 
        <xsl:value-of select="sum(current-group()[lower-case(SI)='false' and lower-case(TI)='false']/Amt)"/> 
       </Amt1> 
       <Amt2> 
        <xsl:value-of select="sum(current-group()[lower-case(SI)='true' and lower-case(TI)='false']/Amt)"/> 
       </Amt2> 
      </LineDetail> 
     </Detail> 
    </xsl:for-each-group> 
</xsl:template> 
</xsl:stylesheet> 
+0

получил. Огромное спасибо. – pinkpanther

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