Reputation: 23
I have an XML with PII.
Example XML:
<DictionarySerializer>
<dictionary xmlns="http://www.kmanage.com/xml/serialization">
<item>
<key>FirstName</key>
<value>John</value>
<type>String</type>
<history>
<value stamp="201405301854095003707" owner="admin" type="String">John</value>
</history>
</item>
<item>
<key>FirstName</key>
<value>John</value>
<type>String</type>
<history>
<value stamp="201405301854095003707" owner="admin" type="String">John</value>
</history>
</item>
<item>
<key>MiddleName</key>
<value>quo</value>
<type>String</type>
<history>
<value stamp="201405301854095003707" owner="admin" type="String">quo</value>
</history>
</item>
<item>
<key>LastName</key>
<value>Dou</value>
<type>String</type>
<history>
<value stamp="201405301854095003707" owner="admin" type="String">Dou</value>
</history>
</item>
</dictionary>
</DictionarySerializer>
I need transform "value" element. Condition replase "key"
My XSLT for replace "value" of one "key":
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:doc="http://www.kmanage.com/xml/serialization">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="doc:item[doc:key/text() = 'FirstName']/doc:value/text()">
<xsl:text>********</xsl:text>
</xsl:template>
</xsl:stylesheet>
I need replace "value" if "key" equal FirstName, LastName, DateOfBirth, Passport and so on...
My result:
<DictionarySerializer>
<dictionary xmlns="http://www.kmanage.com/xml/serialization">
<item>
<key>FirstName</key>
<value>********</value>
<type>String</type>
<history>
<value stamp="201405301854095003707" owner="admin" type="String">John</value>
</history>
</item>
<item>
<key>FirstName</key>
<value>********</value>
<type>String</type>
<history>
<value stamp="201405301854095003707" owner="admin" type="String">John</value>
</history>
</item>
<item>
<key>MiddleName</key>
<value>quo</value>
<type>String</type>
<history>
<value stamp="201405301854095003707" owner="admin" type="String">quo</value>
</history>
</item>
<item>
<key>LastName</key>
<value>Dou</value>
<type>String</type>
<history>
<value stamp="201405301854095003707" owner="admin" type="String">Dou</value>
</history>
</item>
</dictionary>
</DictionarySerializer>
How can I do this without using an array?
Regards, Ilya
Upvotes: 2
Views: 1170
Reputation: 66723
If you want to maintain the list of PII keys inside of your stylesheet, then you could specify a delimited list of key names and test whether the value of the doc:key
(with the delimiter concatenated as a prefix and suffix to avoid partial matches on key names) is contained within the list of delimited PII keys.
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:doc="http://www.kmanage.com/xml/serialization">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="doc:item[contains(
'|FirstName|LastName|DateOfBirth|Passport|',
concat('|', doc:key, '|')
)]/doc:value/text()">
<xsl:text>********</xsl:text>
</xsl:template>
</xsl:stylesheet>
Upvotes: 0
Reputation: 4033
Assuming you want to treat all of keys equally you can use:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:doc="http://www.kmanage.com/xml/serialization">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="doc:item[doc:key = 'FirstName' or doc:key = 'LastName' or doc:key = 'DateOfBirth' or doc:key = 'Passport' or doc:key = 'and so on...']/doc:value/text()">
<xsl:text>********</xsl:text>
</xsl:template>
</xsl:stylesheet>
Though personally I prefer creating a lookup table for those things. You can use exslt for that:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:doc="http://www.kmanage.com/xml/serialization"
xmlns:exsl="http://exslt.org/common">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:variable name="keysXml">
<keys>
<key>FirstName</key>
<key>LastName</key>
<key>DateOfBirth</key>
<!-- add all required keys here -->
</keys>
</xsl:variable>
<xsl:variable name="keys" select="exsl:node-set($keysXml)/keys" />
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="doc:value">
<xsl:choose>
<xsl:when test="$keys/key = ../doc:key">
<xsl:copy>
<xsl:text>********</xsl:text>
</xsl:copy>
</xsl:when>
<xsl:otherwise>
<xsl:copy-of select="."/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>
This way all you need to do is add another entry for another key, which makes maintainability a lot easier.
Upvotes: 1
Reputation: 6397
This stylesheet filters out the value
of a key
matching a list:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:doc="http://www.kmanage.com/xml/serialization" version="1.0">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="doc:value/text()">
<xsl:variable name="associated-key" select="../preceding-sibling::doc:key/text()"/>
<xsl:choose>
<xsl:when test="$associated-key = 'FirstName' or $associated-key = 'LastName' or $associated-key = 'DateOfBirth'">********</xsl:when>
<xsl:otherwise>
<xsl:value-of select="."/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>
You could wring out more elegance by storing the list of filtered keys in a variable and using XPath’s contains
function to see whether the current key matches.
Upvotes: 0
Reputation: 437
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:doc="http://www.kmanage.com/xml/serialization">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="doc:item[doc:key/text() = 'FirstName']/doc:value/text()">
<xsl:text>********</xsl:text>
</xsl:template>
<xsl:template match="doc:item[doc:key/text() = 'LastName']/doc:value/text()">
<xsl:text>******** lastName replacement</xsl:text>
</xsl:template>
</xsl:stylesheet>
Upvotes: 0