2014-09-30 81 views
0

我正在使用XSLT将XML转换为某种文件格式。我排除了匹配两个字段(OrigTxnId和TxnId)的冲销交易。问题是我在标题中为交易数量所做的计数仍包括已被移除的交易。为什么XSLT计数函数无法按预期工作?

。由此输入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> 

的XSLT代码转换成XML:

]]>

<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

你可以尽量减少的例子,只什么必要证明的问题(使你的代码在它可读)?确保也包含一个示例输入XML。 - 另外:XSLT处理(例如计数)输入XML,而不是输出树。 – 2014-09-30 11:52:15

+0

@Michael,我在XSLT代码中引用以下内容:<?NUMRECORDS?> Chris 2014-09-30 12:17:53

+2

我是抱歉,我没有时间编辑您的代码。请发布可以复制,粘贴并运行的内容以显示问题。 – 2014-09-30 12:25:16

回答

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添加条件在您将count语句。

<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 
+0

它完美的作品。最后一个问题,在正文中,我有以下内容: – Chris 2014-10-02 11:17:56

+0

<?SeqNo - 6 - 右对齐,零填充?> Chris 2014-10-02 11:18:34

+0

计数不是连续的。它仍然考虑删除的记录。 – Chris 2014-10-02 11:19:46