XSLT新手(所以我提前道歉)
我有一个包含付款数据的XML文件。我试图将其转换为银行使用的xml格式。如果XML是非美元付款与美元付款,则XML需要不同。在给定文件中可以进行多次付款 这是源XML的示例(简化,一个事务)
<Payments>
<Payment>
<Payment_Detail>
<Payment_Info>
<ns:PAYMENT_Payment_Memo>Payment Info</ns:PAYMENT_Payment_Memo>
<ns:PAYMENT_Payment_Amount>22222</ns:PAYMENT_Payment_Amount>
<ns:PAYMENT_Currency>US Dollars</ns:PAYMENT_Currency>
<ns:PAYMENT_Currency_Code>USD</ns:PAYMENT_Currency_Code>
<ns:PAYMENT_Check_or_Advice_Number>0</ns:PAYMENT_Check_or_Advice_Number>
</Payment_Info>
<Payer_Data>
<ns:PAYER_Company_Name>Company, LLP</ns:PAYER_Company_Name>
<ns:PAYER_Address_Line_1>Main st</ns:PAYER_Address_Line_1>
<ns:PAYER_Address_Line_2>Line 2</ns:PAYER_Address_Line_2>
<ns:PAYER_City>Cleveland</ns:PAYER_City>
<ns:PAYER_Zip_Code>11111</ns:PAYER_Zip_Code>
<ns:PAYER_Country>US</ns:PAYER_Country>
<ns:PAYER_Account_Number>1111-11111111</ns:PAYER_Account_Number>
<ns:PAYER_Currency>USD</ns:PAYER_Currency>
</Payer_Data>
<Payee_Data>
<ns:PAYEE_Name>Name</ns:PAYEE_Name>
<ns:PAYEE_Bank_Name>Bank Name</ns:PAYEE_Bank_Name>
<ns:PAYEE_Bank_Account_Name>Account Name</ns:PAYEE_Bank_Account_Name>
<ns:PAYEE_Account_Number>1111111</ns:PAYEE_Account_Number>
<ns:PAYEE_Masked_Account_Number>**********</ns:PAYEE_Masked_Account_Number>
<ns:PAYEE_Account_Type>DD</ns:PAYEE_Account_Type>
<ns:PAYEE_Routing_Transit_Number>22222</ns:PAYEE_Routing_Transit_Number>
<ns:PAYEE_Bank_Country>US</wpc:PAYEE_Bank_Country>
</Payee_Data>
</Payment_Detail>
</Payment>
</Payments>
我的想法是/是根据货币使用不同的模板。我遇到的问题是在多次付款时确定要调用哪个模板(节点集与单个节点)
这是我的XSL(也简化)
<xsl:variable name="paymentCurrency"
select="/Payment/Payment_Detail/Payment_Info/ns:PAYMENT_Currency_Code"/>
<xsl:choose>
<xsl:when test="$paymentCurrency = 'USD'">
<xsl:call-template name="Payment-Domestic"/>
</xsl:when>
<xsl:otherwise>
<xsl:call-template name="Payment-Foreign"/>
</xsl:otherwise>
</xsl:choose>
<xsl:template name="Payment-Domestic">
<xsl:for-each select="/Payments/Payment">
<paymentrec>
<recordType>2</recordType>
<!-- insert other domestic payment fields -->
</xsl:for-each>
</xsl:template>
<xsl:template name="Payment-Foreign">
<xsl:for-each select="/Payments/Payment">
<paymentrec>
<recordType>5</recordType>
<!-- insert other non US payment fields -->
</xsl:for-each>
</xsl:template>
当输入文件中有单个付款时,它会起作用,但是多个条目将变量设置为节点/值集,并且永远不会匹配。
调用不同模板的最佳方法是什么? 我不应该使用for-each吗? (将XSLT视为命令式语言也不是最聪明的想法,我知道)
由于
编辑回答评论/问题 XSLT 2.0,示例输出(简化如下)
(国外付款)
<paymentrec>
<recordType>5</recordType>
<payerAccNum>1111-11111111</payerAccNum>
<Currency/>
(other fields)
</paymentrec>
(美元付款)
<paymentrec>
<recordType>2</recordType>
<payerAccNum>1111-11111111</payerAccNum>
<payAmount/>
(other fields)
</paymentrec>
它还引出了另一个问题: 如果我有3-4个字段作为国内支付的标题添加(但不是外国的)。我有一个国内支付模板,但如果我在国内&#34;国内&#34;模板,它复制标题。如果我在拨打&#34;付款&#34;模板出现在国外付款中(我不想要)
答案 0 :(得分:0)
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:ns="http://example.edu/" version="1.0">
/* start at the root node... */
<xsl:template match="/Payments">
<root>
<xsl:apply-templates select="Payment"/>
</root>
</xsl:template>
/* then for each "Payment" figure out what it is, call appropriate template */
<xsl:template match="Payment">
<xsl:choose>
<xsl:when test="Payment_Detail/Payment_Info/ns:PAYMENT_Currency_Code='USD'">
<xsl:call-template name="domestic"/>
</xsl:when>
<xsl:otherwise>
<xsl:call-template name="foreign"/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
/* note that these are "rooted" relative to the Payment element */
<xsl:template name="domestic">
<domestic>
<xsl:value-of select="Payment_Detail/Payment_Info/PAYMENT_Payment_Amount"/>
</domestic>
</xsl:template>
<xsl:template name="foreign">
<TODO>
<foreign/>
</TODO>
</xsl:template>
</xsl:stylesheet>
答案 1 :(得分:0)
我会使用多个这样的模板规则:
<xsl:template match="Payment[Payment_Detail/Payment_Info/ns:PAYMENT_Currency_Code='USD']">
<usa>
...
</usa>
</xsl:template>
<xsl:template match="Payment">
<restOfTheWorld>
...
</restOfTheWorld>
</xsl:template>
不需要@thrig使用的额外“路由”模板 - 模板匹配模式可以免费使用。
您的代码使用
<xsl:variable name="paymentCurrency" select="/Payment/Payment_Detail/Payment_Info/ns:PAYMENT_Currency_Code"/>
是错误的,因为以“/”开头的路径表达式相对于文档的根目录选择,而不是相对于您当前正在处理的付款。
(虽然我们处于相对与绝对的主题,但我避免使用“国内”和“外国”这两个术语,因为您希望您的代码对美国以外的人有意义。)