Как я могу поместить результат вычисления с xsl в новый элемент - PullRequest
2 голосов
/ 21 июля 2011

Я использую xsl для расчета совокупного итога по элементу «Базис-продукт».Наконец, выходные данные должны быть помещены в тот же xml, после "Итоговых значений" в некоторых новых элементах, таких как:

<Totals>
 <Totalproduct>
    <Basisproduct>110</Basisproduct>
    <Cumul_Amount>1,52</CustInvoice_LineAmount>
  </Totalproduct>
 <Totalproduct>
    <Basisproduct>198</Basisproduct>
    <Cumul_Amount>294,77</CustInvoice_LineAmount>
  </Totalproduct>
 <Totalproduct>
    <Basisproduct>992</Basisproduct>
    <Cumul_Amount>163,32</CustInvoice_LineAmount>
  </Totalproduct>
 <Totalproduct>
    <Basisproduct>993</Basisproduct>
    <Cumul_Amount>193,78</CustInvoice_LineAmount>
  </Totalproduct>
<Totals>

<-----I have this xml as an input.------>

<?xml version="1.0" encoding="utf-8"?>
<Report Name="SalesInvoice">
    <ReportName>SalesInvoice</ReportName>
  <Invoice>
    <InvoicingName>Test Company</InvoicingName>
  </Invoice>
  <ConditionalArea>
      <BodyCustInvoice>
        <Basisproduct>110</Basisproduct>
        <CustInvoice_LineAmount>1,52</CustInvoice_LineAmount>
      </BodyCustInvoice>
      <BodyCustInvoice>
        <Basisproduct>198</Basisproduct>
        <CustInvoice_LineAmount>20,11</CustInvoice_LineAmount>
      </BodyCustInvoice>
      <BodyCustInvoice>
        <Basisproduct>198</Basisproduct>
        <CustInvoice_LineAmount>20,22</CustInvoice_LineAmount>
      </BodyCustInvoice>
      <BodyCustInvoice>
        <Basisproduct>992</Basisproduct>
        <CustInvoice_LineAmount>3033</CustInvoice_LineAmount>
      </BodyCustInvoice>
      <BodyCustInvoice>
        <Basisproduct>993</Basisproduct>
        <CustInvoice_LineAmount>30,34</CustInvoice_LineAmount>
      </BodyCustInvoice>
      <BodyCustInvoice>
        <Basisproduct>992</Basisproduct>
        <CustInvoice_LineAmount>30,35</CustInvoice_LineAmount>
      </BodyCustInvoice>
      <BodyCustInvoice>
        <Basisproduct>992</Basisproduct>
        <CustInvoice_LineAmount>30.45</CustInvoice_LineAmount>
      </BodyCustInvoice>
      <BodyCustInvoice>
        <Basisproduct>993</Basisproduct>
        <CustInvoice_LineAmount>30,46</CustInvoice_LineAmount>
      </BodyCustInvoice>
      <BodyCustInvoice>
        <Basisproduct>198</Basisproduct>
        <CustInvoice_LineAmount>100.99</CustInvoice_LineAmount>
      </BodyCustInvoice>,      </ConditionalArea>
  <Totals>
  </Totals>
</Report>

xsl, который я использую для вычисления кумулятивной суммы "Basisproduct":

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">              <xsl:output indent="yes"/>       <xsl:strip-space elements="*"/>

<xsl:decimal-format name="EU" decimal-separator="," grouping-separator="."/>

<xsl:key name="KType" match="Basisproduct" use="."/>
    <xsl:template match="node()|@*">
     <xsl:copy>
       <xsl:apply-templates select="node()|@*"/>
     </xsl:copy>
   </xsl:template>

    <xsl:template match="TotalSBasis">
     <TotalSBasis>
       <xsl:for-each select="/*/*/*/Basisproduct [generate-id() = generate-id(key  ('KType', .)[1])]">
         <xsl:variable name="currProd" select="."/>
         <Totalproduct>
           <xsl:copy-of select="."/>
           <Cumul_Amount>
             <xsl:value-of select="sum(/*/*/BodyCustInvoiceTrans  [Basisproduct=$currProd]/CustInvoiceTrans_LineAmount)"/>
           </Cumul_Amount>
         </Totalproduct>
       </xsl:for-each>
           </TotalSBasis>
   </xsl:template>
  </xsl:stylesheet>

Ответы [ 4 ]

0 голосов
/ 22 июля 2011

Это преобразование группирует элементы по Basisproduct и вычисляет общую сумму каждой группы. Обратите внимание, что он включает identity.xsl хорошо известную Преобразование идентичности .


[XSLT 1.0]

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:include href="identity.xsl"/>

    <xsl:key name="KType" match="BodyCustInvoice" use="Basisproduct"/>

    <xsl:template match="Totals">
        <Totals>
            <xsl:apply-templates select="
                preceding-sibling::ConditionalArea[1]/BodyCustInvoice
                [generate-id() 
                = generate-id(key  ('KType', Basisproduct)[1])]" mode="totals"/>
        </Totals>
    </xsl:template>

    <xsl:template match="BodyCustInvoice" mode="totals">
        <Totalproduct>
            <Basisproduct><xsl:value-of select="Basisproduct"/></Basisproduct>
            <Cumul_Amount>  
                <xsl:value-of select="
                    sum(key('KType',Basisproduct)/CustInvoice_LineAmount)"/>
            </Cumul_Amount>
        </Totalproduct>
    </xsl:template>

</xsl:stylesheet>

выход:

<Report Name="SalesInvoice">
   <ReportName>SalesInvoice</ReportName>
   <Invoice>
      <InvoicingName>Test Company</InvoicingName>
   </Invoice>
   <ConditionalArea>
      <BodyCustInvoice>
         <Basisproduct>110</Basisproduct>
         <CustInvoice_LineAmount>1.52</CustInvoice_LineAmount>
      </BodyCustInvoice>
      <BodyCustInvoice>
         <Basisproduct>198</Basisproduct>
         <CustInvoice_LineAmount>20.11</CustInvoice_LineAmount>
      </BodyCustInvoice>
      <BodyCustInvoice>
         <Basisproduct>198</Basisproduct>
         <CustInvoice_LineAmount>20.22</CustInvoice_LineAmount>
      </BodyCustInvoice>
      <BodyCustInvoice>
         <Basisproduct>992</Basisproduct>
         <CustInvoice_LineAmount>30.33</CustInvoice_LineAmount>
      </BodyCustInvoice>
      <BodyCustInvoice>
         <Basisproduct>993</Basisproduct>
         <CustInvoice_LineAmount>30.34</CustInvoice_LineAmount>
      </BodyCustInvoice>
      <BodyCustInvoice>
         <Basisproduct>992</Basisproduct>
         <CustInvoice_LineAmount>30.35</CustInvoice_LineAmount>
      </BodyCustInvoice>
      <BodyCustInvoice>
         <Basisproduct>992</Basisproduct>
         <CustInvoice_LineAmount>30.45</CustInvoice_LineAmount>
      </BodyCustInvoice>
      <BodyCustInvoice>
         <Basisproduct>993</Basisproduct>
         <CustInvoice_LineAmount>30.46</CustInvoice_LineAmount>
      </BodyCustInvoice>
      <BodyCustInvoice>
         <Basisproduct>198</Basisproduct>
         <CustInvoice_LineAmount>100.99</CustInvoice_LineAmount>
      </BodyCustInvoice>
   </ConditionalArea>
   <Totals>
      <Totalproduct>
         <Basisproduct>110</Basisproduct>
         <Cumul_Amount>1.52</Cumul_Amount>
      </Totalproduct>
      <Totalproduct>
         <Basisproduct>198</Basisproduct>
         <Cumul_Amount>141.32</Cumul_Amount>
      </Totalproduct>
      <Totalproduct>
         <Basisproduct>992</Basisproduct>
         <Cumul_Amount>91.13</Cumul_Amount>
      </Totalproduct>
      <Totalproduct>
         <Basisproduct>993</Basisproduct>
         <Cumul_Amount>60.8</Cumul_Amount>
      </Totalproduct>
   </Totals>
</Report>
0 голосов
/ 21 июля 2011

Редактировать: Обновлен мой XSLT, чтобы учесть запрос OP на вставку итогов в исходный XML. Хитрость в решении проблемы состоит в том, чтобы использовать шаблон идентификации и глобальную переменную.

Если вы используете этот XSLT:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:key name="KType" match="Basisproduct" use="."/>
    <xsl:output indent="yes"/>
    <xsl:strip-space elements="*"/>

    <!-- create a variable w/ the calculated totals -->
    <xsl:variable name="CalculatedTotals">
        <xsl:for-each select="*/*/*/Basisproduct [generate-id() = generate-id(key  ('KType', .)[1])]">
            <xsl:element name="TotalProduct">
                <xsl:element name="Basisproduct">
                    <xsl:value-of select= "."/>
                </xsl:element>
                <xsl:element name="Cumul_Amount">
                    <xsl:value-of select= "/*/*/*[Basisproduct = current()][last()]/CustInvoice_LineAmount + sum(/*/*/*[Basisproduct = current()][last()]/preceding-sibling::*/CustInvoice_LineAmount)"/>
                </xsl:element>
            </xsl:element>
        </xsl:for-each>
    </xsl:variable>

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

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

    <xsl:template match="Totals">
        <xsl:copy>
            <!-- insert the calculated totals -->
            <xsl:copy-of select="$CalculatedTotals"/>
        </xsl:copy>
    </xsl:template>
</xsl:stylesheet>

Вы получите этот вывод XML:

<?xml version="1.0" encoding="utf-8"?>
<Report Name="SalesInvoice">
   <ReportName>SalesInvoice</ReportName>
   <Invoice>
      <InvoicingName>Test Company</InvoicingName>
   </Invoice>
   <ConditionalArea>
      <BodyCustInvoice>
         <Basisproduct>110</Basisproduct>
         <CustInvoice_LineAmount>1.52</CustInvoice_LineAmount>
      </BodyCustInvoice>
      <BodyCustInvoice>
         <Basisproduct>198</Basisproduct>
         <CustInvoice_LineAmount>20.11</CustInvoice_LineAmount>
      </BodyCustInvoice>
      <BodyCustInvoice>
         <Basisproduct>198</Basisproduct>
         <CustInvoice_LineAmount>20.22</CustInvoice_LineAmount>
      </BodyCustInvoice>
      <BodyCustInvoice>
         <Basisproduct>992</Basisproduct>
         <CustInvoice_LineAmount>30.33</CustInvoice_LineAmount>
      </BodyCustInvoice>
      <BodyCustInvoice>
         <Basisproduct>993</Basisproduct>
         <CustInvoice_LineAmount>30.34</CustInvoice_LineAmount>
      </BodyCustInvoice>
      <BodyCustInvoice>
         <Basisproduct>992</Basisproduct>
         <CustInvoice_LineAmount>30.35</CustInvoice_LineAmount>
      </BodyCustInvoice>
      <BodyCustInvoice>
         <Basisproduct>992</Basisproduct>
         <CustInvoice_LineAmount>30.45</CustInvoice_LineAmount>
      </BodyCustInvoice>
      <BodyCustInvoice>
         <Basisproduct>993</Basisproduct>
         <CustInvoice_LineAmount>30.46</CustInvoice_LineAmount>
      </BodyCustInvoice>
      <BodyCustInvoice>
         <Basisproduct>198</Basisproduct>
         <CustInvoice_LineAmount>100.99</CustInvoice_LineAmount>
      </BodyCustInvoice>
   </ConditionalArea>
   <Totals>
      <TotalProduct>
         <Basisproduct>110</Basisproduct>
         <Cumul_Amount>1.52</Cumul_Amount>
      </TotalProduct>
      <TotalProduct>
         <Basisproduct>198</Basisproduct>
         <Cumul_Amount>294.77</Cumul_Amount>
      </TotalProduct>
      <TotalProduct>
         <Basisproduct>992</Basisproduct>
         <Cumul_Amount>163.32</Cumul_Amount>
      </TotalProduct>
      <TotalProduct>
         <Basisproduct>993</Basisproduct>
         <Cumul_Amount>193.78000000000003</Cumul_Amount>
      </TotalProduct>
   </Totals>
</Report>

Протестировано с кислородом 12 на Win 7.

0 голосов
/ 21 июля 2011

Что вам нужно сделать, это использовать преобразование идентичности, а затем просто переопределить элемент Totals.

РЕДАКТИРОВАТЬ: Основываясь на комментарии ОП в ответе @ james.garriss, я изменил расчет, чтобы просто суммировать все.

Входной XML

<Report Name="SalesInvoice">
  <ReportName>SalesInvoice</ReportName>
  <Invoice>
    <InvoicingName>Test Company</InvoicingName>
  </Invoice>
  <ConditionalArea>
    <BodyCustInvoice>
      <Basisproduct>110</Basisproduct>
      <CustInvoice_LineAmount>1.52</CustInvoice_LineAmount>
    </BodyCustInvoice>
    <BodyCustInvoice>
      <Basisproduct>198</Basisproduct>
      <CustInvoice_LineAmount>20.11</CustInvoice_LineAmount>
    </BodyCustInvoice>
    <BodyCustInvoice>
      <Basisproduct>198</Basisproduct>
      <CustInvoice_LineAmount>20.22</CustInvoice_LineAmount>
    </BodyCustInvoice>
    <BodyCustInvoice>
      <Basisproduct>992</Basisproduct>
      <CustInvoice_LineAmount>30.33</CustInvoice_LineAmount>
    </BodyCustInvoice>
    <BodyCustInvoice>
      <Basisproduct>993</Basisproduct>
      <CustInvoice_LineAmount>30.34</CustInvoice_LineAmount>
    </BodyCustInvoice>
    <BodyCustInvoice>
      <Basisproduct>992</Basisproduct>
      <CustInvoice_LineAmount>30.35</CustInvoice_LineAmount>
    </BodyCustInvoice>
    <BodyCustInvoice>
      <Basisproduct>992</Basisproduct>
      <CustInvoice_LineAmount>30.45</CustInvoice_LineAmount>
    </BodyCustInvoice>
    <BodyCustInvoice>
      <Basisproduct>993</Basisproduct>
      <CustInvoice_LineAmount>30.46</CustInvoice_LineAmount>
    </BodyCustInvoice>
    <BodyCustInvoice>
      <Basisproduct>198</Basisproduct>
      <CustInvoice_LineAmount>100.99</CustInvoice_LineAmount>
    </BodyCustInvoice>
  </ConditionalArea>
  <Totals> </Totals>
</Report>

Таблица стилей XSLT

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output indent="yes"/>
  <xsl:strip-space elements="*"/>

  <xsl:key name="KType" match="Basisproduct" use="."/>

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

  <xsl:template match="Totals">
    <Totals>
      <xsl:for-each select="/*/*/*/Basisproduct [generate-id() = generate-id(key  ('KType', .)[1])]">
        <xsl:variable name="currProd" select="."/>
        <Totalproduct>
          <xsl:copy-of select="."/>
          <Cumul_Amount>
            <!--<xsl:value-of select= "/*/*/*[Basisproduct = current()][last()]/CustInvoice_LineAmount + sum(/*/*/*[Basisproduct = current()][last()]/preceding-sibling::*/CustInvoice_LineAmount)"/>-->
            <xsl:value-of select="sum(/*/*/BodyCustInvoice[Basisproduct=$currProd]/CustInvoice_LineAmount)"/>
          </Cumul_Amount>
        </Totalproduct>
      </xsl:for-each>      
    </Totals>
  </xsl:template>

</xsl:stylesheet>

Выходной XML (с использованием Xalan :-()

<Report Name="SalesInvoice">
   <ReportName>SalesInvoice</ReportName>
   <Invoice>
      <InvoicingName>Test Company</InvoicingName>
   </Invoice>
   <ConditionalArea>
      <BodyCustInvoice>
         <Basisproduct>110</Basisproduct>
         <CustInvoice_LineAmount>1.52</CustInvoice_LineAmount>
      </BodyCustInvoice>
      <BodyCustInvoice>
         <Basisproduct>198</Basisproduct>
         <CustInvoice_LineAmount>20.11</CustInvoice_LineAmount>
      </BodyCustInvoice>
      <BodyCustInvoice>
         <Basisproduct>198</Basisproduct>
         <CustInvoice_LineAmount>20.22</CustInvoice_LineAmount>
      </BodyCustInvoice>
      <BodyCustInvoice>
         <Basisproduct>992</Basisproduct>
         <CustInvoice_LineAmount>30.33</CustInvoice_LineAmount>
      </BodyCustInvoice>
      <BodyCustInvoice>
         <Basisproduct>993</Basisproduct>
         <CustInvoice_LineAmount>30.34</CustInvoice_LineAmount>
      </BodyCustInvoice>
      <BodyCustInvoice>
         <Basisproduct>992</Basisproduct>
         <CustInvoice_LineAmount>30.35</CustInvoice_LineAmount>
      </BodyCustInvoice>
      <BodyCustInvoice>
         <Basisproduct>992</Basisproduct>
         <CustInvoice_LineAmount>30.45</CustInvoice_LineAmount>
      </BodyCustInvoice>
      <BodyCustInvoice>
         <Basisproduct>993</Basisproduct>
         <CustInvoice_LineAmount>30.46</CustInvoice_LineAmount>
      </BodyCustInvoice>
      <BodyCustInvoice>
         <Basisproduct>198</Basisproduct>
         <CustInvoice_LineAmount>100.99</CustInvoice_LineAmount>
      </BodyCustInvoice>
   </ConditionalArea>
   <Totals>
      <Totalproduct>
         <Basisproduct>110</Basisproduct>
         <Cumul_Amount>1.52</Cumul_Amount>
      </Totalproduct>
      <Totalproduct>
         <Basisproduct>198</Basisproduct>
         <Cumul_Amount>141.32</Cumul_Amount>
      </Totalproduct>
      <Totalproduct>
         <Basisproduct>992</Basisproduct>
         <Cumul_Amount>91.13</Cumul_Amount>
      </Totalproduct>
      <Totalproduct>
         <Basisproduct>993</Basisproduct>
         <Cumul_Amount>60.8</Cumul_Amount>
      </Totalproduct>
   </Totals>
</Report>
0 голосов
/ 21 июля 2011
<Totals>
  <xsl:for-each select="*/*/*/Basisproduct [generate-id() = generate-id(key  ('KType', .)[1])]">
    <Totalproduct>
      <Basisproduct><xsl:value-of select= "."/></Basisproduct>
      <Cumul_Amount>
        <xsl:value-of select= "/*/*/*[Basisproduct = current()][last()]/CustInvoice_LineAmount + sum(/*/*/*[Basisproduct = current()][last()]/preceding-sibling::*/CustInvoice_LineAmount)"/>
      </Cumul_Amount>
    </Totalproduct>
  </xsl:for-each>
</Totals>

Это выведет xml в указанной форме с результатами, которые вы показали.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...