我正在尝试更新以下xml中的信用卡号码,tokenize无法正常工作,请您查看我在这里缺少的信息?
输入XML:
<Payment>
<CreditCardDetails>
<CreditCard>
<Amount>31.0</Amount>
<CreditCardType>American Express</CreditCardType>
<CreditHolderName>test</CreditHolderName>
<Number>41111111111111</Number>
<ExpiryMonth>8</ExpiryMonth>
<ExpiryYear>2015</ExpiryYear>
</CreditCard>
<CreditCard>
<Amount>31.0</Amount>
<CreditCardType>AMERICAN EXPRESS</CreditCardType>
<CreditHolderName></CreditHolderName>
<Number>34123456544333</Number>
<ExpiryMonth>8</ExpiryMonth>
<ExpiryYear>2015</ExpiryYear>
</CreditCard>
<CreditCard>
<Amount>31.0</Amount>
<CreditCardType>Visa</CreditCardType>
<CreditHolderName>exman</CreditHolderName>
<Number>43434343434434343</Number>
<ExpiryMonth>8</ExpiryMonth>
<ExpiryYear>2015</ExpiryYear>
</CreditCard>
</CreditCardDetails>
</Payment>
我正在尝试的XSLT:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"
xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns:str="http://exslt.org/strings"
exclude-result-prefixes="#all" >
<xsl:output method="xml" cdata-section-elements="Payment" omit-xml-declaration="yes" />
<!-- copy all elements and their attributes-->
<xsl:template match="* | @*">
<xsl:copy><xsl:copy-of select="@*"/><xsl:apply-templates/></xsl:copy>
</xsl:template>
<xsl:template match="/">
<xsl:copy><xsl:copy-of select="@*"/><xsl:apply-templates/></xsl:copy>
</xsl:template>
<xsl:template match="//*[local-name()='Payment']">
<xsl:variable name="inXML" select="text()"/>
<xsl:variable name="updatedCards">
<xsl:variable name="openCardDetailsTag"><xsl:value-of select="'<CreditCardDetails>'"/></xsl:variable>
<xsl:variable name="closeCardDetailsTag"><xsl:value-of select="'</CreditCardDetails>'"/></xsl:variable>
<xsl:variable name="openCNTag"><xsl:value-of select="'<Number>'"/></xsl:variable>
<xsl:variable name="closeCNTag"><xsl:value-of select="'</Number>'"/></xsl:variable>
<xsl:variable name="openCCTag"><xsl:value-of select="'<CreditCardType>'"/></xsl:variable>
<xsl:variable name="closeCCTag"><xsl:value-of select="'</CreditCardType>'"/></xsl:variable>
<xsl:variable name="allcreditCards" select="normalize-space(substring-before(substring-after($inXML,$openCardDetailsTag),$closeCardDetailsTag))"/>
<xsl:for-each select="str:tokenize($allcreditCards,'<CreditCard>')">
<xsl:variable name="Number" select="normalize-space(substring-before(substring-after(.,$openCNTag),$closeCNTag))"/>
<xsl:variable name="IncomingccType" select="normalize-space(substring-before(substring-after(.,$openCCTag),$closeCCTag))"/>
<xsl:variable name="BeforeCreditcard" select="normalize-space(substring-before(.,$openCNTag))"/>
<xsl:variable name="AfterCreditcard" select="normalize-space(substring-after(.,$closeCNTag))"/>
<xsl:variable name="newCard">
<xsl:call-template name="updateCard">
<xsl:with-param name="ccNum" select="$Number"/>
<xsl:with-param name="ccType" select="$IncomingccType"/>
</xsl:call-template>
</xsl:variable>
<xsl:variable name="updatedCards">
<xsl:value-of select="concat($updatedCards,$beforeCardNumber,$openCardNumberTag,$newCard,$closeCardNumberTag,$afterCardNumber)"/>
</xsl:variable>
</xsl:for-each>
<xsl:element name="Payment" >
<xsl:value-of select="$updatedCards"/>
</xsl:element>
</xsl:template>
<xsl:template name="updateCard">
<xsl:param name="ccNum"/>
<xsl:param name="ccType"/>
<xsl:variable name="firstDigit" select="substring($ccNum,1,1)"/>
<xsl:variable name="firstTwoDigits" select="substring($ccNum,1,2)"/>
<xsl:variable name="ccTypeFromNumber">
<xsl:choose>
<xsl:when test="firstTwoDigits ='34' or $firstTwoDigits ='37'">
<xsl:value-of select="'AMERICAN EXPRESS'"/>
</xsl:when>
<xsl:when test="$firstDigit ='4'">
<xsl:value-of select="'Visa'"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="UNKNOWN"></xsl:value-of>
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:choose>
<xsl:when test="$ccType = $ccTypeFromNumber">
<xsl:value-of select="concat($ccNum,$ccType)"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="WrongNumber"/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>
期待OUTPUT XML:
<Payment>
<CreditCardDetails>
<CreditCard>
<Amount>31.0</Amount>
<CreditCardType>American Express</CreditCardType>
<CreditHolderName>test</CreditHolderName>
<Number>WrongNumber</Number>
<ExpiryMonth>8</ExpiryMonth>
<ExpiryYear>2015</ExpiryYear>
</CreditCard>
<CreditCard>
<Amount>31.0</Amount>
<CreditCardType>AMERICAN EXPRESS</CreditCardType>
<CreditHolderName></CreditHolderName>
<Number>34123456544333AMERICAN EXPRESS</Number>
<ExpiryMonth>8</ExpiryMonth>
<ExpiryYear>2015</ExpiryYear>
</CreditCard>
<CreditCard>
<Amount>31.0</Amount>
<CreditCardType>Visa</CreditCardType>
<CreditHolderName>exman</CreditHolderName>
<Number>41111111111111111Visa</Number>
<ExpiryMonth>8</ExpiryMonth>
<ExpiryYear>2015</ExpiryYear>
</CreditCard>
</CreditCardDetails>
</Payment>
尝试用NewNumber替换信用卡号码,我可以知道如何实现这个目标吗?
答案 0 :(得分:1)
str:tokenize($allcreditCards,'<CreditCard>')
这不能按预期工作,因为第二个参数中的每个字符被视为分隔字符 - 请参阅:http://www.exslt.org/str/functions/tokenize/index.html
您可以使用递归处理模板自行“标记”输入。
修改后的样式:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.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="/">
<Payment>
<xsl:call-template name="replaceNumbers">
<xsl:with-param name="string" select="Payment" />
</xsl:call-template>
</Payment>
</xsl:template>
<xsl:template name="replaceNumbers">
<xsl:param name="string"/>
<xsl:param name="openNum" select="'<Number>'"/>
<xsl:param name="closeNum" select="'</Number>'"/>
<xsl:param name="openType" select="'<CreditCardType>'"/>
<xsl:param name="closeType" select="'</CreditCardType>'"/>
<xsl:choose>
<xsl:when test="contains($string, $openNum) and contains(substring-after($string, $openNum), $closeNum)" >
<xsl:value-of select="substring-before($string, $openNum)" />
<xsl:value-of select="$openNum" />
<xsl:call-template name="updateCard">
<xsl:with-param name="ccType" select="substring-before(substring-after($string, $openType), $closeType)" />
<xsl:with-param name="ccNum" select="substring-before(substring-after($string, $openNum), $closeNum)" />
</xsl:call-template>
<xsl:value-of select="$closeNum" />
<!-- recurse -->
<xsl:call-template name="replaceNumbers">
<xsl:with-param name="string" select="substring-after($string, $closeNum)" />
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$string"/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template name="updateCard">
<xsl:param name="ccType"/>
<xsl:param name="ccNum"/>
<!-- INSERT YOUR PROCESS HERE -->
<xsl:value-of select="concat($ccNum, $ccType)" />
</xsl:template>
</xsl:stylesheet>
注意:您可能希望包含更多测试,如果在之前没有类型的情况下CC可能会进入。