At a recent project I needed to implement functionality which would store an incoming message in a relational database. Since we were using the WSO2 platform I created a WSO2 DataService for this by generating a Data WebService based in my MySQL table. Each message supplied to this service in the following XML format would be inserted in a MySQL database.
<?xml version="1.0" encoding="UTF-8"?> <xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema"> <xs:element name="originalMessage" type="originalMessageType"/> <xs:complexType name="originalMessageType"> <xs:sequence> <xs:element type="xs:string" name="id"/> <xs:element type="xs:string" name="content"/> </xs:sequence> </xs:complexType> </xs:schema>
Of course it was a little more complex XML but the idea remains. The content of these two elements were stored in a table ‘ARCHIVE’ which had 2 columns ‘ID’ and ‘MESSAGE’. The tricky part was how to get the original XML message in the ‘content’ element of the ‘Data Service’ format. The original message format was:
<?xml version="1.0" encoding="UTF-8"?> <xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema"> <xs:element name="message" type="messageType"/> <xs:complexType name="messageType"> <xs:sequence> <xs:element type="xs:string" name="messageID"/> <xs:element type="xs:string" name="order"/> <xs:element type="xs:string" name="price"/> </xs:sequence> </xs:complexType> </xs:schema>
Well, it turned out to be quite easy (although not possible with my favorite mapping tool Altova Mapforce). I just had to ‘escape’ the XML that is put in the ‘content’ element as CDATA part. The XSLT that does this looks like:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:template match="/"> <originalMessage> <id> <xsl:value-of select="/message/messageID" /> </id> <content> <xsl:text disable-output-escaping="yes"><![CDATA[</xsl:text> <xsl:copy-of select="/"/> <xsl:text disable-output-escaping="yes">]]></xsl:text> </content> </originalMessage> </xsl:template> </xsl:stylesheet>
This will transform an input XML message like this:
<message> <messageID>123</messageID> <order>abc</order> <price>123,45</price> </message>
To the result XML:
<?xml version="1.0" encoding="UTF-8"?> <originalMessage> <id>123</id> <content><![CDATA[<message> <messageID>123</messageID> <order>abc</order> <price>123,45</price> </message>]]></content> </originalMessage>
And this XML can be stored in the database by the WSO2 Data Service without a problem as it complies with the XSD of the Data Service.