sbutt Posted April 3, 2012 Share Posted April 3, 2012 (edited) Hi Folks, I am looking for a solution as to how I can mask some data that is part of a CDATA element. My currently implemented xslt-1 script works fine when my xml element/attribute is not placed inside cdata, for example, in the following xml snippet, I masked <CreditCardNumber> element's data: Input XML: <?xml version="1.0" encoding="UTF-8"?><fareRequest da="true"><vcrs> <vcr>U2</vcr></vcrs><fareTypes/><tourOps/><flights> <flight depApt="SXF" depDate="2012-04-19" dstApt="BUD"/> <flight depApt="BUD" depDate="2012-04-25" dstApt="SXF"/></flights><CreditCardNumber>123456123</CreditCardNumber><limit>20</limit><offset>0</offset><waitOnList> <waitOn>ALL</waitOn></waitOnList><coses/></fareRequest> XSLT-1 Script: <?xml version="1.0" encoding="UTF-8"?><xsl:stylesheet version="1.2" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:ota="http://www.opentravel.org/OTA/2003/05" xmlns:anyway="http://anyway.com/webservices/" xmlns:k="http://webservices.kuoni.ch" xmlns:xft="http://www.exchangefortravel.org/xft/current" xmlns:tu="http://tempuri.org/" xmlns:jet2="http://Jet2.Com/External/2009/01/V4"><xsl:output encoding="UTF-8" version="1.0" method="xml" indent="yes" cdata-section-elements="anyway:request k:request k:ForwardRequestResult xft:NameText xft:Description xft:URL xft:From xft:To xft:Code tu:XRq tu:ProcessTransactionXFTUResult libelle nom prenom adresse1 ville pays email"/><xsl:strip-space elements="*"/><!--add coma separated element names without namespace prefix to be masked, dont remove first coma! --><xsl:param name="names">!,Number,CCV,cc_number,cc_cvv,AccountNumber,CardSecurityCode,card_number,options,CreditCardNumber,CardNumber,IssueNumber,SecurityCode,</xsl:param><xsl:template match="/"> <xsl:apply-templates select="node()"/></xsl:template><xsl:template match="@*"> <xsl:variable name="attr-name" select="concat(',' , local-name() , ',')"/> <xsl:attribute name="{name()}" namespace="{namespace-uri()}"> <xsl:choose> <xsl:when test="string-length(substring-before($names, $attr-name)) > 0"> <xsl:call-template name="mask"/> </xsl:when> <xsl:otherwise> <xsl:value-of select="."/> </xsl:otherwise> </xsl:choose> </xsl:attribute></xsl:template><xsl:template match="text()"> <xsl:copy/></xsl:template><xsl:template match="*"> <xsl:variable name="el-name" select="concat(',' , local-name(), ',')"/> <xsl:choose> <xsl:when test="string-length(substring-before($names, $el-name)) > 0"> <xsl:element name="{name()}" namespace="{namespace-uri()}"> <xsl:call-template name="mask"/> </xsl:element> <xsl:apply-templates select="@*"/> <xsl:apply-templates select="*"/> </xsl:when> <xsl:otherwise> <xsl:element name="{name()}" namespace="{namespace-uri()}"> <xsl:apply-templates select="@*"/> <xsl:apply-templates/> </xsl:element> </xsl:otherwise> </xsl:choose></xsl:template><xsl:template name="index-of"> <xsl:param name="param1"/> <xsl:param name="param2"/> <xsl:value-of select="string-length(substring-before(concat(' ' ,$param1), $param2))"/></xsl:template><xsl:template name="mask"> <xsl:variable name="length" select="string-length(.)"/> <xsl:choose> <xsl:when test="$length > 3"> <xsl:value-of select="concat ('************', substring(.,$length - 1, 2))"/> </xsl:when> <xsl:when test="$length > 1">***</xsl:when> <xsl:otherwise/> </xsl:choose></xsl:template></xsl:stylesheet> Output XML: <?xml version="1.0" encoding="UTF-8"?><fareRequest da="true"><vcrs> <vcr>U2</vcr></vcrs><fareTypes/><tourOps/><flights> <flight depApt="SXF" depDate="2012-04-19" dstApt="BUD"/> <flight depApt="BUD" depDate="2012-04-25" dstApt="SXF"/></flights><CreditCardNumber>************23</CreditCardNumber><limit>20</limit><offset>0</offset><waitOnList> <waitOn>ALL</waitOn></waitOnList><coses/></fareRequest> In the above example <CreditCardNumber>************23</CreditCardNumber> is masked properly. But when in my XML, I have the following scenario: <?xml version="1.0" encoding="UTF-8"?><fareRequest da="true"><vcrs> <vcr>U2</vcr></vcrs><fareTypes/><tourOps/><flights> <flight depApt="SXF" depDate="2012-04-19" dstApt="BUD"/> <flight depApt="BUD" depDate="2012-04-25" dstApt="SXF"/></flights><![CDATA[<CreditCardNumber>123456123</CreditCardNumber>]]><limit>20</limit><offset>0</offset><waitOnList> <waitOn>ALL</waitOn></waitOnList><coses/></fareRequest> That is <CreditCardNumber> inside CDATA, the script does not mask the data. Or in other words, everything that is contained inside CDATA, is ignored because it is not considered as an element or attribute by the xslt processor. Could somebody help me out in fixing this problem? Please note that my script is in XSLT 1. Thanks. Edited April 3, 2012 by sbutt Link to comment Share on other sites More sharing options...
DVezina Posted May 7, 2012 Share Posted May 7, 2012 Here is one way without using multiple passes on the file. <xsl:template match="text()"><xsl:choose><xsl:when test="contains(.,'<CreditCardNumber>')"><!-- This is the CDATA that I want to mask and write back out as CDATA --> <xsl:variable name="tcontent"><xsl:value-of select="substring-after(substring-before(.,'</CreditCardNumber>'),'<CreditCardNumber>') "/> </xsl:variable> <xsl:text disable-output-escaping="yes"><![CDATA[<CreditCardNumber></xsl:text> <xsl:call-template name="maskVariable"> <xsl:with-param name="tvar" select="$tcontent"/> </xsl:call-template> <xsl:text disable-output-escaping="yes"></CreditCardNumber>]]></xsl:text></xsl:when><xsl:otherwise> <xsl:copy/></xsl:otherwise></xsl:choose></xsl:template> <xsl:template name="maskVariable"> <xsl:param name="tvar"/> <xsl:variable name="length" select="string-length($tvar)"/> <xsl:choose> <xsl:when test="$length > 3"> <xsl:value-of select="concat ('************', substring($tvar,$length - 1, 2))"/> </xsl:when> <xsl:when test="$length > 1">***</xsl:when> <xsl:otherwise/> </xsl:choose></xsl:template> Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now