转置 xml 交易数据在 xslt2 中显示为 html 表格

问题描述 投票:0回答:1

获得以下 xml 数据,它在非常简单的级别上“模拟”一些银行帐户交易(仅取款):

<trnsctns>
 <trnsctn date="19/01/01">
  <OB>100</OB>
  <amnt/>   
 </trnsctn> 
 <trnsctn date="19/03/03">  
  <OB/>
  <amnt>33</amnt>
 </trnsctn>
 <trnsctn date="19/02/02">
  <OB/>
  <amnt>22</amnt>
 </trnsctn>
 <trnsctn date="19/05/05">
  <OB/>
  <amnt>7</amnt>
 </trnsctn>
 <trnsctn date="19/04/04">
  <date>19-04-04</date>
  <OB/>
  <amnt>32</amnt> 
 </trnsctn>
</trnsctns>

其中 amnt 是当月从初始 OB=100(期初余额)提取的金额; 如果没有提取金额,则初始余额保持不变(如第一个月 - 没有金额,因此 2002 年 2 月 19 日交易日 OB 的值仍为 100,依此类推)和 CB(期末余额) -是一个计算字段 - 有一个非常简单的公式 = OB - amnt,但有一个注释:当前 CB(计算字段) 成为下一个OB..

<table border="1" style="border-collapse:collapse">
 <tr><th>crrntNmbr</th><td>1</td><td>2</td><td>3</td><td>4</td><td>5</td></tr>
  <tr><th>OB</th><td>100</td><td>100</td><td>78</td><td>45</td><td>13</td></tr> 
  <tr><th>amnt</th><td>-</td><td>22</td><td>33</td><td>32</td><td>7</td></tr>
  <tr><th>CB</th><td>100</td><td>78</td><td>45</td><td>13</td><td>6</td></tr>
 <tr><th>date</th><td>19/01/01</td><td>19/02/02</td><td>19/03/03</td><td>19/04/01</td><td>19/05/05</td></tr>
</table>

生成的 html 表中的字段顺序也需要与显示的完全一致;人们很容易注意到它与 xml 数据文件中的顺序不同......

近似的 xslt 转换如下(有很多错误......需要修复)

<xsl:template match="/">
 <table border="1" style="border-collapse:collapse">
  <tr><th>crrntNmbr</th>
     <xsl:for-each select="trnsctns/trnsctn">
      <td><xsl:number/></td>
     </xsl:for-each>
   </tr>
  <!-- rows for OB, amount, CB, and date -->
   <xsl:for-each select="trnsctns/trnsctn[1]/*">
     <xsl:variable name="fldNme" select="name()"/>  <!-- adaugata a doua oara -->
      <tr><th><xsl:value-of select="name()"/></th>
       <xsl:for-each select="//trnsctn/*[name()=$fldNme]"> 
         <xsl:variable name="OB" select="trnsctn[position()]/OB"/>
         <xsl:variable name="amt" select="trnsctn[position()]/amnt"/>
         <xsl:variable name="CB" select="$OB - $amt"/> <!-- error ! -->
           <td><xsl:choose>
                <xsl:when test="name() = 'OB'">
                 <xsl:value-of select="."/>
                </xsl:when>
                <xsl:when test="name() = 'amnt'">
                  <xsl:value-of select="."/>
                 </xsl:when>
                 <xsl:when test="name() = 'date'">
                  <xsl:value-of select="."/>
                 </xsl:when>
                 <xsl:otherwise>
                  <xsl:value-of select="$CB"/>  <!-- not good also .. -->
                 </xsl:otherwise>
                </xsl:choose>
            </td>
           </xsl:for-each>
          </tr>
        </xsl:for-each>
      </table>
    </xsl:template>

xslt 2,请帮我解决这个问题.. 预先感谢..

xml xslt
1个回答
0
投票

对于一个问题来说,这里的问题太多了。

尝试以此为起点;它展示了如何对交易进行排序(假设格式为 DD/MM/YY),然后按顺序处理它们并处理空的

amnt
:

XSLT 2.0

<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:template match="/trnsctns">
    <table border="1">
        <tr>
            <th>date</th>
            <th>ob</th>
            <th>amnt</th>
            <th>cb</th>
        </tr>
        <xsl:call-template name="process">
            <xsl:with-param name="transactions" as="element()*">
                <xsl:perform-sort select="trnsctn">
                    <xsl:sort select="replace(@date, '(.{2})/(.{2})/(.{2})', '$3$2$1')"/>
                </xsl:perform-sort> 
            </xsl:with-param>
        </xsl:call-template>
    </table>
</xsl:template>

<xsl:template name="process">
    <xsl:param name="transactions"/>
    <xsl:param name="tx" select="$transactions[1]" />
    <xsl:param name="ob" select="$tx/OB" />
    <xsl:variable name="amnt" select="$tx/amnt" />
    <xsl:variable name="amnt" select="if ($amnt/text()) then number($amnt) else 0" />
    <xsl:variable name="cb" select="$ob - $amnt" />
    <tr>
        <td>
            <xsl:value-of select="$tx/@date"/>
        </td>   
        <td>
            <xsl:value-of select="$ob"/>
        </td>
        <td>
            <xsl:value-of select="$amnt"/>
        </td>
        <td>
            <xsl:value-of select="$cb"/>
        </td>
    </tr>
    <xsl:if test="count($transactions) > 1">
        <xsl:call-template name="process">
            <xsl:with-param name="transactions" select="$transactions[position() > 1]"/>
            <xsl:with-param name="ob" select="$cb"/>
        </xsl:call-template>
    </xsl:if>   
</xsl:template>

</xsl:stylesheet>

结果(渲染):

© www.soinside.com 2019 - 2024. All rights reserved.