为什么XSLT计数功能不能正常工作?

时间:2014-09-30 11:42:56

标签: xslt

我正在使用XSLT将XML转换为某种文件格式。我排除了匹配两个字段(OrigTxnId和TxnId)的逆转交易。问题是我在标题中所做的计数仍然包括已被删除的交易。

此处输入XML exsample:

<XML>
<Record><GroupId>10028</GroupId><Id>1</Id><User>CHRISVI</User><TxnId>264-10028-1-516739-2</TxnId><Date>30-Sep-2014</Date><Time>12:21:24</Time><Account>12440531</Account><Amount>217090</Amount><AllowableMOP>0</AllowableMOP><BankBranchCode>280071</BankBranchCode><ChequeAccNo>62247628681</ChequeAccNo><ChequeNo>000040</ChequeNo></Record>
<Record><GroupId>10028</GroupId><Id>1</Id><User>CHRISVI</User><TxnId>264-10028-1-516743-2</TxnId><Date>30-Sep-2014</Date><Time>12:21:52</Time><Account>10895388</Account><Amount>150000</Amount><AllowableMOP>1</AllowableMOP></Record>
<Record><GroupId>10028</GroupId><Id>1</Id><User>CHRISVI</User><TxnId>264-10028-1-516748-1</TxnId><Date>30-Sep-2014</Date><Time>12:22:26</Time><OrigTxnId>264-10028-1-516743-2</OrigTxnId><Account>10895388</Account><Amount>150000</Amount><AllowableMOP>1</AllowableMOP></Record>
<Record><GroupId>10028</GroupId><Id>1</Id><User>CHRISVI</User><TxnId>264-10028-1-516756-1</TxnId><Date>30-Sep-2014</Date><Time>12:23:01</Time><Account>10895388</Account><Amount>10000</Amount><AllowableMOP>1</AllowableMOP></Record>
<Record><GroupId>10028</GroupId><Id>1</Id><User>CHRISVI</User><TxnId>264-10028-1-516760-2</TxnId><Date>30-Sep-2014</Date><Time>12:23:24</Time><Account>10605762</Account><Amount>15000</Amount><AllowableMOP>1</AllowableMOP></Record>
</XML>

转换XML的XSLT代码:

]]&GT;     

<xsl:key name="original" match="/XML/Record" use="TxnId" />
<xsl:key name="copy" match="/XML/Record" use="OrigTxnId" /> 

<xsl:template match="/">
    <?Header Starts?>
    <xsl:value-of select="user:IncrementBatchNo('Batchcow','C:\WebRiposte\Agents\Configuration\Configurations.xml')"/>
    <?RECORDTYPE?>
    <xsl:text>H</xsl:text>
    <?FILETYPE?>
    <xsl:text>PNP</xsl:text>
    <?COMPANYCODE?>
    <xsl:text>WHK</xsl:text>
    <?COMPANYNAME?>
    <xsl:text>                   Windhoek Municipality</xsl:text>
    <?ACTIONDATETIME?>
    <xsl:value-of  select="user:getdatetime()"/>
    <?PAYMENTBATCHNO?>
    <xsl:value-of select="format-number(user:GetBatchNo('Batchcow','C:\WebRiposte\Agents\Configuration\Configurations.xml'),'000000')"/>
    <?RECORDSIZE?>
    <xsl:text>000256</xsl:text>
    <?NUMRECORDS?>
    <xsl:value-of select="format-number(count(//SessionId),'000000')"/>
    <?TESTLIVE?>
    <xsl:text>L</xsl:text>
    <?FILLER?>
    <xsl:call-template name="pad-some-space">
        <xsl:with-param name="currentlength" select="1"/>
        <xsl:with-param name="newlength" select="177"/>
    </xsl:call-template>
    <?Line Feed?>
    <xsl:text>&#10;</xsl:text>
    <?Header Ends ?>
    <?Body Starts?>
    <xsl:for-each select="XML/Record[not(key('original', OrigTxnId) or key('copy', TxnId))]">
        <?Record Type - 1 - Fixed value “D”(etail)?>
        <xsl:text>D</xsl:text>
        <?PAYMENTBATCHNO?>
        <xsl:value-of select="format-number(user:GetBatchNo('Batchcow','C:\WebRiposte\Agents\Configuration\Configurations.xml'),'000000')"/>
        <?SeqNo - 6 - Right justified, zero padded?>
        <xsl:value-of select="format-number(count(preceding-sibling::Record)+1, '000000')"/>
        <?CompanyCode - 3 - Leave Blank, Space padded?>
        <xsl:text>WHK</xsl:text>
        <?CustAccountNo - 20 - Right justified, zero padded?>
        <xsl:value-of select="format-number(Account, '00000000000000000000')"/>
        <?Invoice No and Ref no?>
        <xsl:text>0000000000000000000000000</xsl:text>
        <?Create Group id Variable?>
        <xsl:variable name="GroupId" select="GroupId"/>
        <?NamPostBranch - 50 - ?>
        <xsl:call-template name="reformat-string-length">
            <xsl:with-param name="value" select="user:GetPostOfficeName(string($GroupId),'C:\WebRiposte\Agents\Configuration\Configurations.xml')"/>
            <xsl:with-param name="str-len" select="50"/>
        </xsl:call-template>
        <?NamPostReceiptNo - 16 - Group-Node-Sequence No?>
        <xsl:call-template name="reformat-string-length">
            <xsl:with-param name="value" select="substring(SessionId,5,16)"/>
            <xsl:with-param name="str-len" select="16"/>
            <xsl:with-param name="alignment" select=" 'right' "/>
        </xsl:call-template>
        <?MOPCheck?>            
         <xsl:choose>
            <xsl:when test="ChequeNo &gt; 0">
                <xsl:text>1</xsl:text>
                <?BankBranchCode - 6 - space padded?>
                <xsl:call-template name="reformat-string-length">
                      <xsl:with-param name="value" select="BankBranchCode"/>
                      <xsl:with-param name="str-len" select="6"/>
                    </xsl:call-template>                
                <?ChequeAccountNo -15- Left justified, space padded?>
                <xsl:call-template name="reformat-string-length">
                      <xsl:with-param name="value" select="ChequeAccNo"/>
                      <xsl:with-param name="str-len" select="15"/>
                    </xsl:call-template>                    
                <?ChequeNo - 6 - Right justified, zero padded?>
                <xsl:value-of select="format-number(ChequeNo, '000000')"/>
            </xsl:when>
            <xsl:otherwise>
                <xsl:text>2</xsl:text>
                <?BankBranchCode - 6 - space padded?>
                <xsl:text>&#160;&#160;&#160;&#160;&#160;&#160;</xsl:text>
                <?ChequeAccountNo -15- Left justified, space padded?>
                <xsl:text>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;</xsl:text>
                <?ChequeNo - 6 - Right justified, zero padded?>
                <xsl:value-of select="format-number(0, '000000')"/>
            </xsl:otherwise>
        </xsl:choose>
        <?PayAmountCents - 9 - Right justified, zero padded?>
        <xsl:value-of select="format-number(Amount, '000000000')"/>
        <?PaymentDateTime (YYYYMMDDHHMMSS)?>
        <xsl:value-of select="substring(Date,8,4)"/>
        <xsl:call-template name="format-month-3letter-to-number">
            <xsl:with-param name="month-3letter" select="substring(Date,4,3)"/>
        </xsl:call-template>
        <xsl:value-of select="substring(Date,1,2)"/>
        <xsl:value-of select="substring(Time,1,2)"/>
        <xsl:value-of select="substring(Time,4,2)"/>
        <xsl:value-of select="substring(Time,7,2)"/>
        <?Entry Mode?>
        <xsl:text>M</xsl:text>
        <?AmountSign - 1- ?>
        <xsl:text>D</xsl:text>
        <?Filler?>
        <xsl:call-template name="pad-some-space">
            <xsl:with-param name="currentlength" select="1"/>
            <xsl:with-param name="newlength" select="77"/>
        </xsl:call-template>
        <?Line?>
        <xsl:text>&#10;</xsl:text>
    </xsl:for-each>
    <?Body Ends?>
    <?Trailer Starts?>
    <?RECORDTYPE?>
    <xsl:text>T</xsl:text>
    <?COMPANYCODE?>
    <xsl:text>WHK</xsl:text>
    <?PAYMENTBATCHNO?>
    <xsl:value-of select="format-number(user:GetBatchNo('Batchcow','C:\WebRiposte\Agents\Configuration\Configurations.xml'),'000000')"/>
    <?TOTALAMOUNTCENTS?>
    <xsl:value-of select="format-number(sum(//Amount), '00000000000')"/>
    <?AMOUNTSIGN?>
    <xsl:text>D</xsl:text>
    <?FILLER?>
    <xsl:call-template name="pad-some-space">
        <xsl:with-param name="currentlength" select="1"/>
        <xsl:with-param name="newlength" select="235"/>
    </xsl:call-template>
    <?Trailer Ends?>
</xsl:template>
<?Support functions ------------------- ?>
<?Date time format?>
<xsl:template name="format-date-time">
    <xsl:param name="currdatetime"/>
    <xsl:value-of select="concat(substring($currdatetime,1,4),substring($currdatetime,6,2),substring($currdatetime,9,2),substring($currdatetime,12,2),substring($currdatetime,15,2),substring($currdatetime,18,2))"/>
</xsl:template>
<?Convert month from text to number?>
<xsl:template name="format-month-3letter-to-number">
    <xsl:param name="month-3letter"/>
    <xsl:variable name="MonthName" select="'Jan01Feb02Mar03Apr04May05Jun06Jul07Aug08Sep09Oct10Nov11Dec12'"/>
    <xsl:value-of select="substring(concat(substring-after($MonthName,$month-3letter),'00'),1,2)"/>
</xsl:template>
<?Pad space?>
<xsl:template name="pad-some-space">
    <xsl:param name="currentlength"/>
    <xsl:param name="newlength"/>
    <xsl:if test="number($currentlength) &lt; number($newlength)">
        <xsl:text> </xsl:text>
        <xsl:call-template name="pad-some-space">
            <xsl:with-param name="currentlength" select="number($currentlength)+1"/>
            <xsl:with-param name="newlength" select="$newlength"/>
        </xsl:call-template>
    </xsl:if>
</xsl:template>
<?Evaluate-string-length?>
<xsl:template name="reformat-string-length">
    <xsl:param name="value"/>
    <xsl:param name="str-len"/>
    <xsl:choose>
        <xsl:when test="string-length($value) &gt; number($str-len)">
            <xsl:value-of select="substring($value,1,$str-len)"/>
        </xsl:when>
        <xsl:otherwise>
            <xsl:value-of select="$value"/>
            <xsl:call-template name="pad-some-space">
                <xsl:with-param name="currentlength" select="string-length($value)"/>
                <xsl:with-param name="newlength" select="number($str-len)"/>
            </xsl:call-template>
        </xsl:otherwise>
    </xsl:choose>
</xsl:template>

1 个答案:

答案 0 :(得分:0)

简化问题总是好的。虽然它涉及一些猜测工作,但我将你的问题简化为

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

  <xsl:key name="original" match="/XML/Record" use="TxnId"/>
  <xsl:key name="copy" match="/XML/Record" use="OrigTxnId"/>

  <xsl:template match="/">
    <xsl:value-of select="format-number(count(//GroupId),'000000')"/>
    <xsl:text>&#10;</xsl:text>
    <xsl:for-each select="XML/Record[not(key('original', OrigTxnId) or key('copy', TxnId))]">
      <xsl:value-of select="format-number(Account, '00000000000000000000')"/>
     <xsl:text>&#10;</xsl:text>
    </xsl:for-each>
  </xsl:template>
</xsl:stylesheet>

(请注意,正如我的评论所述,我已将<xsl:value-of select="format-number(count(//Session),'000000')"/>替换为<xsl:value-of select="format-number(count(//GroupId),'000000')"/>

这将输出以下内容

000005
00000000000012440531
00000000000010895388
00000000000010605762

所以,第一个计数表示5个项目,但只有3行。

现在,在您的代码中,您有xsl:for-each

<xsl:for-each 
     select="XML/Record[not(key('original', OrigTxnId) or key('copy', TxnId))]">

因此,您需要做的就是将xsl:for-each中的条件添加到您的计数声明中。

 <xsl:value-of 
      select="format-number(count(XML/Record[not(key('original', OrigTxnId) or key('copy', TxnId))]/GroupId),'000000')"/>

最好使用变量来删除重复编码。

举个例子,试试这个XSLT作为基础

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

  <xsl:key name="original" match="/XML/Record" use="TxnId"/>
  <xsl:key name="copy" match="/XML/Record" use="OrigTxnId"/>

  <xsl:template match="/">
    <xsl:variable name="records" select="XML/Record[not(key('original', OrigTxnId) or key('copy', TxnId))]" />
    <xsl:value-of select="format-number(count($records/GroupId),'000000')"/>
    <xsl:text>&#10;</xsl:text>
    <xsl:for-each select="$records">
      <xsl:value-of select="format-number(Account, '00000000000000000000')"/>
     <xsl:text>&#10;</xsl:text>
    </xsl:for-each>
  </xsl:template>
</xsl:stylesheet>

这输出以下内容:

000003
00000000000012440531
00000000000010895388
00000000000010605762