1

I have requirement where I have to add Namespace and xsi to the element from the source xml with No Namespace. In Source XML I am just getting the Nodes and there is No namespace and another program needs BizTalk to add Namespace and XSI to the XML for its processing.

I tried:

  1. Used add namespace pipeline component. (It just added namespace and not the xsi bits)
  2. Used Map for putting up the desired format and yes no luck as got just the namespace.

Need your help around this.

My source XML is like

<?xml version="1.0" encoding="UTF-16"?> 
<Document>
    <CstmrPmtStsRpt>
        <GrpHdr>
            <MsgId></MsgId>
            <CreDtTm></CreDtTm>
            <InitgPty>                 
                <Id>
                    <OrgId>
                        <BICOrBEI></BICOrBEI>
                    </OrgId>
                </Id>
            </InitgPty>
        </GrpHdr>
        <OrgnlGrpInfAndSts>
             <OrgnlMsgId></OrgnlMsgId>
            <OrgnlMsgNmId></OrgnlMsgNmId>
            <OrgnlNbOfTxs></OrgnlNbOfTxs>
            <OrgnlCtrlSum></OrgnlCtrlSum>
            <GrpSts>ACCP</GrpSts>
        </OrgnlGrpInfAndSts>
    </CstmrPmtStsRpt>
</Document>

My Required format is as below:

<?xml version="1.0" encoding="UTF-8"?>
<Document xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns="MyNamespace">     
    <CstmrPmtStsRpt>
        <GrpHdr>
            <MsgId></MsgId>
            <CreDtTm></CreDtTm>
            <InitgPty>                 
                <Id>
                    <OrgId>
                        <BICOrBEI></BICOrBEI>
                    </OrgId>
                </Id>
            </InitgPty>
        </GrpHdr>
        <OrgnlGrpInfAndSts>
            <OrgnlMsgId></OrgnlMsgId>
            <OrgnlMsgNmId></OrgnlMsgNmId>
            <OrgnlNbOfTxs></OrgnlNbOfTxs>
            <OrgnlCtrlSum></OrgnlCtrlSum>
            <GrpSts>ACCP</GrpSts>
        </OrgnlGrpInfAndSts>
    </CstmrPmtStsRpt>
</Document>
Dijkgraaf
  • 11,049
  • 17
  • 42
  • 54
Ramjeet
  • 33
  • 5
  • Very important question, why? It's a very weird scenario where one system produces content in the Empty Namespace but another system requires the exact same structure in a Namespace. This seems like a communication problem between them, and not really your problem to solve. – Johns-305 Apr 25 '18 at 01:42
  • Be aware "MyNamespace" is not a valid URI and can't be used. – Johns-305 Apr 25 '18 at 01:50

2 Answers2

4

Use the namespace attribute of xsl:element like this:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    version="2.0">

    <xsl:output method="xml" indent="yes"/>

    <xsl:template match="*">
        <xsl:element name="{local-name()}" namespace="MyNamespace">
            <xsl:namespace name="xsi" select="'http://www.w3.org/2001/XMLSchema-instance'"/>
            <xsl:apply-templates/>
        </xsl:element>
    </xsl:template>
</xsl:stylesheet>

Edit: Since you need to work with XSLT-1.0. Use following stylesheet:

<?xml version="1.0" encoding="UTF-16"?> 
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

    <xsl:output method="xml" indent="yes"/>

    <xsl:template match="/Document">
        <Document xmlns="MyNamespace" 
            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
            <xsl:apply-templates/>           
        </Document>
    </xsl:template>

    <xsl:template match="*">
        <xsl:element name="{local-name()}" namespace="MyNamespace">
            <xsl:apply-templates/>
        </xsl:element>
    </xsl:template>

</xsl:stylesheet>

Note, that you need to know your rootnode's name for this (in this case Document).

FelHa
  • 1,043
  • 11
  • 24
  • Hi Ferestes, This is throwing error 'xsl:template' cannot be a child of the 'xsl:template' element. – Ramjeet Apr 24 '18 at 15:49
  • Hi , I receive XML without any namespace , and I need to map all of the fields to the target schema, which is exactly the same and being created just for adding the namespace. – Ramjeet Apr 24 '18 at 15:51
  • 1
    To add as a note, the `xsl:namespace` only works with XSLT-2.0 and above and not with XSLT-1.0. – zx485 Apr 24 '18 at 15:51
  • You cannot place a template into a template. xsl:stylesheet contains the templates. Please add your xsl-code at your question for further help. – FelHa Apr 24 '18 at 15:53
  • Hi Ferestes, I have to actually create some XSL code as I just have source and destination schema and there is a requirement of adding Namespace and xsi in the target.As I have pasted the desired output. – Ramjeet Apr 24 '18 at 15:56
  • I did tried this earlier If this makes a sense – Ramjeet Apr 24 '18 at 15:59
  • 2
    Although this is the correct answer for XSLT 2.0, the question is regarding BizTalk Server which only allows XSLT 1.0. Unfortunately this is not stated by OP. – zurebe-pieter Apr 24 '18 at 16:08
  • I did tried the same XSL and got this error "Exception has been thrown by the target of an invocation. 'namespace' is not a recognized extension element. An error occurred at (9,18)." – Ramjeet Apr 24 '18 at 16:11
  • Also, when I changed the version to 1.0 in the xsl, got 'xsl:namespace' cannot be a child of the 'xsl:element' element error – Ramjeet Apr 24 '18 at 16:15
  • I edited the answer. @Ramjeet. The code in your comment has some logical and some syntax errors. – FelHa Apr 24 '18 at 16:22
  • Thanks Ferrstes, I will try using the XSL you have changed – Ramjeet Apr 24 '18 at 16:26
  • If you have attributes etc. in your XML document, you will have to add a template for those nodes. See here: https://stackoverflow.com/questions/15981488/how-can-i-add-namespaces-to-the-root-element-of-my-xml-using-xslt – FelHa Apr 24 '18 at 16:28
  • Hi Ferestes, its throwing error btm1046: Output validation error: Could not find schema information for the element 'MyNamespace:Id'. for all of the fields in my xml – Ramjeet Apr 24 '18 at 16:38
  • This has nothing to do with the question or the code above. It is because "MyNamespace" is not known by the schema you are working with. – FelHa Apr 24 '18 at 16:49
  • Hi Ferestes, I have in my project a source schema and destination schema, as marked in question. I am using a map to add this namespace and xsi. I am saving the xsl and using it on map by referencing the same.Please let me know what else I have to do. I just want to copy everything on the source to destination with namespace and xsi added to Document Element – Ramjeet Apr 24 '18 at 16:53
  • I can't help you with that since your problems do not relate on your XML or the script I've shown you. You asked for a XSLT script and you got XML as required in your question. – FelHa Apr 24 '18 at 17:29
  • Hi Ferestes,As I have told you that I am using exactly the same xsl with the same source and destination as mentioned above.But the xsl is failing. let me try it again with some changes and update you all with the same. Thanks a lot in advance. – Ramjeet Apr 24 '18 at 17:54
  • @Ferestes Good answer, but OP is using BizTalk Server and this is not how to resolve this in a BizTalk app. Again, nothing wrong with the Answer, it's just not for BizTalk. – Johns-305 Apr 25 '18 at 01:47
1

BizTalk Answer:

First, it's a good thing the incoming document has no namespace. Xml Namespaces are far, far, far more trouble than they're worth and should be avoided/removed whenever possible.

Second the output format is not valid Xml. "MyNamespace" is not a valid URI and can't be used for a Namespace. If this is what they are asking for, they need to fix that first.

But, if you must, your process should not be "add a namespace". What you're really doing is Transforming from SysA's Document to SysB's Document. For that, use a Map. You will use to practially identical Schemas, one with and one without the Target Namespace.

The Mapper will handle xsi for you as well, if it's needed.

Johns-305
  • 10,908
  • 12
  • 21
  • Hi John, I have actually created two schema, Source with no Namespace and Target with Namespace and XSI bits. With Map and mass copy functoid , am able to get the target namespace but not getting the xsi in the element. Please help me if there is any way on the same. – Ramjeet Apr 26 '18 at 14:23
  • @Ramjeet You don't need the xsi unless there are nodes in the xsi namespace, which you don't have. If the receiver is insisting that it just be there, they have a misunderstand of how this works...you solve that problem by insisting they accept valid xml. Did you try it? What specifically happened? – Johns-305 Apr 27 '18 at 01:36
  • By this approach i was able to get the xml in desired format when i tested the map and debugged it. With using it on receive port with Pass Through pipeline this is failing.I cannot use XML receive as i have no namespace in my incoming schema.Please let me know if there is any workaround for the same. – Ramjeet May 01 '18 at 08:33
  • I am thinking of using Add namespace pipeline component in Receive side and once namespace is added I can fire the map for getting xsi added.But not sure how to add xsi bit only on the namespace already been there. Converting to – Ramjeet May 01 '18 at 08:36