如何在XSLT的bodys模板中获取headers校验值更新TxRsnSts
解决方案
要实现headers校验结果影响bodys里的TxRsnSts节点状态,核心是把headers的校验结果传递到bodys模板中。由于XSLT变量是模板作用域,无法直接跨模板访问,我们可以将校验逻辑移到根模板中计算,再通过参数传递给两个子模板。
修改步骤及完整代码
- 根模板中预计算headers的校验标志:将原headers模板内的校验逻辑移到根模板,计算出三个校验结果变量,让headers和bodys模板都能复用。
- 修改headers模板:接收预计算好的校验标志,直接输出即可。
- 修改bodys模板:添加参数接收headers的校验标志,在TxRsnStsB的判断中使用这些值。
- 调整模板调用:在调用headers和bodys时传入对应的参数。
修改后的完整XSLT代码:
<xsl:stylesheet version="1.0" xmlns:fn="http://www.w3.org/2005/xpath-functions" xmlns:ns1="urn:iso:std:iso:20022:tech:xsd:head.001.001.01" xmlns:ns2="urn:iso:std:iso:20022:tech:xsd:pacs.002.001.10" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output indent="no" method="xml" omit-xml-declaration="yes"/> <xsl:template match="/"> <!-- 根模板中预计算headers的校验标志 --> <xsl:variable name="CpyDplctSrc" select="//BusMsg/AppHdr/CpyDplct"/> <xsl:variable name="flagCpyDplcts"> <xsl:choose> <xsl:when test="$CpyDplctSrc = ''"/> <xsl:when test="string-length($CpyDplctSrc) <= 35 and ($CpyDplctSrc = 'CODU' or $CpyDplctSrc = 'COPY' or $CpyDplctSrc = 'DUPL')"> <xsl:value-of select="$CpyDplctSrc"/> </xsl:when> <xsl:otherwise> <xsl:copy> <xsl:copy-of select="$CpyDplctSrc"/> </xsl:copy> <xsl:value-of select="'U0002'"/> </xsl:otherwise> </xsl:choose> </xsl:variable> <xsl:variable name="PssblDplctSrc" select="//BusMsg/AppHdr/PssblDplct"/> <xsl:variable name="flagPssblDplcts"> <xsl:choose> <xsl:when test="$PssblDplctSrc = ''"/> <xsl:when test="string-length($PssblDplctSrc) <= 35 and ($PssblDplctSrc = 'true' or $PssblDplctSrc = 'false')"> <xsl:value-of select="$PssblDplctSrc"/> </xsl:when> <xsl:otherwise> <xsl:copy> <xsl:copy-of select="$PssblDplctSrc"/> </xsl:copy> <xsl:value-of select="'U0002'"/> </xsl:otherwise> </xsl:choose> </xsl:variable> <xsl:variable name="SgntrSrc" select="//BusMsg/AppHdr/Sgntr"/> <xsl:variable name="flagSgntrs"> <xsl:choose> <xsl:when test="$SgntrSrc = ''"/> <xsl:when test="string-length($SgntrSrc) <= 35"> <xsl:value-of select="$SgntrSrc"/> </xsl:when> <xsl:otherwise> <xsl:copy> <xsl:copy-of select="$SgntrSrc"/> <!-- 修正原代码笔误,原代码误用了$PssblDplctSrc --> </xsl:copy> <xsl:value-of select="'U0012'"/> </xsl:otherwise> </xsl:choose> </xsl:variable> <ns:BusMsg xmlns:ns="urn:iso" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="urn:iso ../../../xsd/phase1/MainCIHub.xsd"> <ns1:AppHdr> <!-- 调用headers模板时传入预计算的校验标志 --> <xsl:call-template name="headers"> <xsl:with-param name="flagCpyDplcts" select="$flagCpyDplcts"/> <xsl:with-param name="flagPssblDplcts" select="$flagPssblDplcts"/> <xsl:with-param name="flagSgntrs" select="$flagSgntrs"/> </xsl:call-template> </ns1:AppHdr> <ns:Document> <ns:FIToFIPmtStsRpt> <!-- 调用bodys模板时传入headers的校验标志 --> <xsl:call-template name="bodys"> <xsl:with-param name="CtgyPurpB" select="//BusMsg/Document/FItoFICstmrCdtTrf/CdtTrfTxInf/PmtTpInf/CtgyPurp/Prtry"/> <xsl:with-param name="IntrBkSttlmAmtB" select="//BusMsg/Document/FItoFICstmrCdtTrf/CdtTrfTxInf/IntrBkSttlmAmt/Value"/> <xsl:with-param name="CcyB" select="//BusMsg/Document/FItoFICstmrCdtTrf/CdtTrfTxInf/IntrBkSttlmAmt/Ccy"/> <xsl:with-param name="flagCpyDplcts" select="$flagCpyDplcts"/> <xsl:with-param name="flagPssblDplcts" select="$flagPssblDplcts"/> <xsl:with-param name="flagSgntrs" select="$flagSgntrs"/> </xsl:call-template> </ns:FIToFIPmtStsRpt> </ns:Document> </ns:BusMsg> </xsl:template> <xsl:template name="headers"> <!-- 接收校验标志参数 --> <xsl:param name="flagCpyDplcts"/> <xsl:param name="flagPssblDplcts"/> <xsl:param name="flagSgntrs"/> <ns1:CpyDplct> <xsl:value-of select="$flagCpyDplcts"/> </ns1:CpyDplct> <ns1:PssblDplct> <xsl:value-of select="$flagPssblDplcts"/> </ns1:PssblDplct> <ns1:Sgntr> <xsl:value-of select="$flagSgntrs"/> </ns1:Sgntr> </xsl:template> <xsl:template name="bodys"> <xsl:param name="CtgyPurpB"/> <xsl:param name="IntrBkSttlmAmtB"/> <xsl:param name="CcyB"/> <!-- 接收headers的校验标志参数 --> <xsl:param name="flagCpyDplcts"/> <xsl:param name="flagPssblDplcts"/> <xsl:param name="flagSgntrs"/> <xsl:variable name="flagCtgyPurpBs"> <xsl:variable name="payT" select="substring($CtgyPurpB,1,3)"/> <xsl:variable name="catP" select="substring($CtgyPurpB,4,2)"/> <xsl:choose> <xsl:when test="not(contains($payT,'010') or contains($payT,'011') or contains($payT,'019') or contains($payT,'110') or contains($payT,'510') or contains($payT,'610') or contains($payT,'710') or contains($payT,'720') or contains($payT,'000'))"> <xsl:value-of select="'U0002'"/> </xsl:when> <xsl:when test="not(contains($catP,'01') or contains($catP,'02') or contains($catP,'03') or contains($catP,'99'))"> <xsl:value-of select="'U0002'"/> </xsl:when> <xsl:otherwise> <xsl:value-of select="$CtgyPurpB"/> </xsl:otherwise> </xsl:choose> </xsl:variable> <xsl:variable name="flagIntrBkSttlmAmtBs"> <xsl:variable name="amount" select="substring-before($IntrBkSttlmAmtB,'.')"/> <xsl:variable name="decimal" select="substring-after($IntrBkSttlmAmtB,'.')"/> <xsl:choose> <xsl:when test="not(fn:matches($IntrBkSttlmAmtB, '^[0-9.]*$'))"> <xsl:value-of select="'U0038'"/> </xsl:when> <xsl:when test="not(string-length($amount) <= 16)"> <xsl:value-of select="'U0038'"/> </xsl:when> <xsl:when test="not(string-length($decimal) <= 2)"> <xsl:value-of select="'U0038'"/> </xsl:when> <xsl:otherwise> <xsl:value-of select="$IntrBkSttlmAmtB"/> </xsl:otherwise> </xsl:choose> </xsl:variable> <xsl:variable name="flagCcyBs"> <xsl:choose> <xsl:when test="not(fn:matches($CcyB, '^[a-zA-Z0-9]*$') and string-length($CcyB) <= 3)"> <xsl:value-of select="'U0038'"/> </xsl:when> <xsl:otherwise> <xsl:value-of select="$CcyB"/> </xsl:otherwise> </xsl:choose> </xsl:variable> <ns1:CtgyPurp> <xsl:value-of select="$flagCtgyPurpBs"/> </ns1:CtgyPurp> <ns1:IntrBkSttlmAmt> <xsl:value-of select="$flagIntrBkSttlmAmtBs"/> </ns1:IntrBkSttlmAmt> <ns1:Ccy> <xsl:value-of select="$flagCcyBs"/> </ns1:Ccy> <xsl:variable name="TxRsnStsB"> <xsl:choose> <xsl:when test="contains($flagSgntrs, 'U0012') or contains($flagSgntrs, 'U0002') or contains($flagSgntrs, 'U0038') or contains($flagPssblDplcts, 'U0012') or contains($flagPssblDplcts, 'U0002') or contains($flagPssblDplcts, 'U0038') or contains($flagCpyDplcts, 'U0012') or contains($flagCpyDplcts, 'U0002') or contains($flagCpyDplcts, 'U0038') or contains($flagCtgyPurpBs, 'U0012') or contains($flagCtgyPurpBs, 'U0002') or contains($flagCtgyPurpBs, 'U0038') or contains($flagIntrBkSttlmAmtBs, 'U0012') or contains($flagIntrBkSttlmAmtBs, 'U0002') or contains($flagIntrBkSttlmAmtBs, 'U0038') or contains($flagCcyBs, 'U0012') or contains($flagCcyBs, 'U0002') or contains($flagCcyBs, 'U0038')"> <xsl:value-of select="'Decline'" /> </xsl:when> <xsl:otherwise> <xsl:value-of select="'Approve'" /> </xsl:otherwise> </xsl:choose> </xsl:variable> <ns1:TxRsnSts><xsl:value-of select="$TxRsnStsB"/></ns1:TxRsnSts> </xsl:template> </xsl:stylesheet>
关键说明
- 将headers的校验逻辑移到根模板后,校验结果成为根模板的变量,可通过
<xsl:with-param>传递给任意子模板。 - 修正了原代码中
flagSgntrs变量里的笔误(误用$PssblDplctSrc应为$SgntrSrc),避免校验逻辑错误。 - bodys模板现在能直接访问headers的校验结果,实现了headers校验不通过时修改TxRsnSts状态的需求。
内容的提问来源于stack exchange,提问作者Tos Mario
相关产品推荐
相关产品推荐

