In my case,The Input xml must have a declaration of namespace of which the root element (i.e. <message>
) is part of .
In the example 1,<message>
element is a part of namespace http://www.origostandards.com/schema/mtg/v2
.It is declared in the xml and the <message>
element is present in the xml with the prefix mtg
.The styelesheet which I have developed conforms to this requirement, but doesn't preserve the namespace for other elements than the root element.
If namespace of which the message element is a part of, is not declared (example2), then the styelesheet must produce an output having the default namespace http://www.origoservices.com
declared in the root element.(See example2)
However, the stylesheet which I have developed works well in case of (example 2) which doesn't have the namespace prefixes assigned to the elements and doesn't work for the xmls having namespace element names prefixed with namespace (example1).
Example 1 input xml
<?xml version="1.0"?>
<mtg:message xmlns:ce="http://www.origostandards.com/schema/ce/v2" xmlns:mtg="http://www.origostandards.com/schema/mtg/v2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<mtg:m_control id="m_control1">
<mtg:control_timestamp>2014-12-18T10:06:00-05:00</mtg:control_timestamp>
<mtg:message_id>c5-a4e0-aa0090358c7f</mtg:message_id>
<mtg:retry_number>0</mtg:retry_number>
<mtg:expected_response_type>synchronous</mtg:expected_response_type>
<mtg:initiator_id>temp</mtg:initiator_id>
<mtg:responder_id/>
</mtg:m_control>
<ce:m_content>
<ce:b_control>
<ce:reference>xyz</ce:reference>
</ce:b_control>
</ce:m_content>
</mtg:message>
Actual output
<?xml version="1.0" encoding="UTF-8"?>
<mtg:message xmlns:ce="http://www.origostandards.com/schema/ce/v2" xmlns:mtg="http://www.origostandards.com/schema/mtg/v2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<m_control xmlns="http://www.origostandards.com/schema/mtg/v2" id="m_control1">
<control_timestamp>2014-12-18T10:06:00-05:00</control_timestamp>
<message_id>c5-a4e0-aa0090358c7f</message_id>
<retry_number>0</retry_number>
<expected_response_type>synchronous</expected_response_type>
<initiator_id>temp</initiator_id>
<responder_id/>
</m_control>
<m_content xmlns="http://www.origostandards.com/schema/mtg/v2">
<b_control>
<reference>xyz</reference>
</b_control>
</m_content>
</mtg:message>
Expected Output
<?xml version="1.0"?>
<mtg:message xmlns:ce="http://www.origostandards.com/schema/ce/v2" xmlns:mtg="http://www.origostandards.com/schema/mtg/v2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<mtg:m_control id="m_control1">
<mtg:control_timestamp>2014-12-18T10:06:00-05:00</mtg:control_timestamp>
<mtg:message_id>c5-a4e0-aa0090358c7f</mtg:message_id>
<mtg:retry_number>0</mtg:retry_number>
<mtg:expected_response_type>synchronous</mtg:expected_response_type>
<mtg:initiator_id>temp</mtg:initiator_id>
<mtg:responder_id/>
</mtg:m_control>
<ce:m_content>
<ce:b_control>
<ce:reference>xyz</ce:reference>
</ce:b_control>
</ce:m_content>
</mtg:message>
Example 2 - Stylesheet is working as expected for this Input xml
<message>
<m_control>
<control_timestamp>2014-11-05T09:30:38.308</control_timestamp>
<retry_number>0</retry_number>
<expected_response_type>synchronous</expected_response_type>
<responder_id>Exchange Life 1</responder_id>
</m_control>
</message>
Expected and Actual Output
<message xmlns="http://www.origoservices.com">
<m_control>
<control_timestamp>2014-11-05T09:30:38.308</control_timestamp>
<retry_number>0</retry_number>
<expected_response_type>synchronous</expected_response_type>
<responder_id>Exchange Life 1</responder_id>
</m_control>
</message>
My stylesheet
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:dp="http://www.datapower.com/extensions" xmlns:regexp="http://exslt.org/regular-expressions" extension-element-prefixes="dp" xmlns:exsl="http://exslt.org/common" exclude-result-prefixes="dp regexp exsl">
<xsl:output method="xml" indent="yes" version="1.0"/>
<xsl:variable name="origo-svc-ns" select="'http://www.origoservices.com'"/>
<!--xsl:template match="/message"-->
<xsl:template match="/*[local-name()='message']">
<xsl:variable name="name" select="name()"/>
<xsl:variable name="namespace-in" select="namespace-uri(/*[1])"/>
<xsl:variable name="initiator_id" select="/*[local-name()='message']/*[local-name()='m_control']/*[local-name()='initiator_id']"/>
<!--Below code tests if default namespace declaration is present. If not, then assigns the 'default namespace' to 'namespace' variable. Also, it assigns context variable "AddNamespace" with value "Y" if default namespace declaration is not present -->
<xsl:variable name="namespace">
<xsl:choose>
<xsl:when test="$namespace-in = '' and ($initiator_id = 'True Potential' or $initiator_id = '2Plan' or $initiator_id = '356356536' or $initiator_id = 'Assyst Software') ">
<xsl:value-of select="$origo-svc-ns"/>
<dp:set-variable name="'var://context/FL/AddNamspace'" value="'Y'"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$namespace-in"/>
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<!-- - In below statement, {$namespace} will copy over the default namespace declarartion to the destination.
- copy-of select statement will copy over all the namespace declaration in the source xml
- apply-template will copy over evrything else from the source to destination
- xsl:element wil create an element node (in this case <message> ) in the destination document.
-->
<xsl:element name="{$name}" namespace="{$namespace}">
<xsl:copy-of select="namespace::*"/>
<xsl:apply-templates select="@*|node()|comment()|processing-instruction()|text()">
<xsl:with-param name="ns-uri" select="$namespace"/>
</xsl:apply-templates>
</xsl:element>
</xsl:template>
<xsl:template match="node()">
<xsl:param name="ns-uri"/>
<xsl:element name="{local-name()}" namespace="{$ns-uri}">
<xsl:copy-of select="namespace::*"/>
<xsl:apply-templates select="@*|node()|comment()|processing-instruction()|text()">
<xsl:with-param name="ns-uri" select="$ns-uri"/>
</xsl:apply-templates>
</xsl:element>
</xsl:template>
<xsl:template match="@*|comment()|processing-instruction()|text()">
<xsl:param name="ns-uri"/>
<xsl:copy>
<xsl:apply-templates select="@*|node()|comment()|processing-instruction()|text()">
<xsl:with-param name="ns-uri" select="$ns-uri"/>
</xsl:apply-templates>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
Example of the xml having default namespace declared http://www.origoservices.com is a default namespace in the below example.
<message xmlns="http://www.origoservices.com" xmlns:a="https://www.bbb.com">
<m_control>
<control_timestamp>2014-11-05T09:30:38.308</control_timestamp>
<message_id>2840c35d-d294-4179-baa1-55ea2ce0b9ac</message_id>
<retry_number>0</retry_number>
<message_type>Quotation Request</message_type>
<message_version>/origo/3.7/QNBPensionAnnuityQuoteRequest.xsd</message_version>
<expected_response_type>synchronous</expected_response_type>
<initiator_id>Friends Provident</initiator_id>
<initiator_orchestration_id>2944460</initiator_orchestration_id>
<responder_id>Exchange Life 1</responder_id>
</m_control>
</message>