Removing unwanted namespaces from a BizTalk Map

BizTalk is a great tool but sometimes the output is a little unreadable because of the number of namespaces in a document.
This post is related to a previous post where I had to import a zillion schemas. Once I had those schema's imported I could map them but the ouput looked as the picture below.

So about 120 namespace declarations and then some data. (the namespace declaration was about 10K and the message itself only 5K) This was not what the customer desired and they wanted to get rid of some (most) of those namespaces.
So I created a nice little CSLT that would get rid of those namespaces. I started a discussion on MSDN <clickto see> and Greg Forsythe came with the following solution.
Create a custom XSLT like this :

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
   <xsl:template match="*">
      <xsl:element name="{local-name()}" namespace="{namespace-uri()}">
         <xsl:apply-templates select="@* | node()"/>
     </xsl:element>
  </xsl:template>
<xsl:template match="@* | text() | comment() | processing-instruction()">
   <xsl:copy/> 
</xsl:template>
</xsl:stylesheet>


And surely that did the trick.
But there was a problem. I now had to execute two maps. One to map to the desired output and one to get rid of all those namespaces.
Furthermore this script had the problem that instead of declaring all the namespaces once at the top of the document, it repeated the namespaces in every node, resulting in a much less readable message.

Leg xmlns="urn:fec:florecom:xml:data:draft:ReusableAggregateBusinessInformationEntity:3">
      <TransportMeans>
        <TypeCode xmlns="urn:un:unece:uncefact:data:standard:ReusableAggregateBusinessInformationEntity:3" listID="Recommendation 28" listAgencyID="6" listVersionID="2007"/>
      </TransportMeans>
      <SpecifiedLoadingLocation>
        <CountryID schemeVersionID="second edition 2006"/>
      </SpecifiedLoadingLocation>

After googling around I came to a solution where I had the following problems solved.

  • No extra map required
  • Namespaces declared only once per message
  • High level of control of what namespace to declare and what namespace to omit.

Here is how I did it :

  • First Create the map as you normally do.
  • Then after the map is finished, select validate map.
  • You will be presented with something like this :

 D:\Lokale Bestanden\Ontwikkeling\CE\FH.CE\FH.CCE.CCX.Plugins.XMLLB_v0006\FH.CCE.CCX.Plugins.XMLLB_v0006\Maps\GeleverdePartij_v0006_To_Delivery_0p2.btm: warning btm1004: The destination node "TypeCode" has multiple inputs but none of its ancestors is connected to a looping functoid.
D:\Lokale Bestanden\Ontwikkeling\CE\FH.CE\FH.CCE.CCX.Plugins.XMLLB_v0006\FH.CCE.CCX.Plugins.XMLLB_v0006\Maps\GeleverdePartij_v0006_To_Delivery_0p2.btm: The output XSLT is stored in the following file:
file:///C:\Documents and Settings\pkwk\Local Settings\Temp\1\_MapData\GeleverdePartij_v0006_To_Delivery_0p2.xsl
D:\Lokale Bestanden\Ontwikkeling\CE\FH.CE\FH.CCE.CCX.Plugins.XMLLB_v0006\FH.CCE.CCX.Plugins.XMLLB_v0006\Maps\GeleverdePartij_v0006_To_Delivery_0p2.btm: The Extension Object XML is stored in the following file: <file:///C:\Documents and Settings\pkwk\Local Settings\Temp\1\_MapData\GeleverdePartij_v0006_To_Delivery_0p2_extxml.xml>

  •  Now test the map and see if it still gives the same result (it should)
  • Then open the Custom.xsl and look  for "exclude-result-prefixes"
  • Then I added all the namespaces I wanted to exclude to this so it looked like this :

exclude-result-prefixes

="msxsl var s2 s0 s1 userCSharp udt qdt ns1 ns2 ns3 ns4 ns5 ns6 ns7 ns8 ns9 ns10 ns11 ns12 ns13 ns14 ns15 ns16 ns17 ns18 ns19 ns20 ns21 ns22 ns23 ns24 ns25 ns26 ns27 ns28 ns29 ns30 ns31 ns32 ns33 ns34 ns35 ns36 ns37 ns38 ns39 ns40 ns41 ns42 ns43 ns44 ns45 ns46 ns47 ns48 ns49 ns50 ns51 ns52 ns53 ns54 ns55 ns56 ns57 ns58 ns59 ns60 ns61 ns62 ns63 ns64 ns65 ns66 ns67 ns68 ns69 ns70 ns71 ns72 ns73 ns74 ns75 ns76 ns77 ns78 ns79 ns80 ns81 ns82 ns83 ns84 ns85 ns86 ns87 ns88 ns89 ns90 ns91 ns92 ns93 ns94 ns95 ns96 ns97 ns98 ns99 ns100 ns101 ns102 ns103 ns104 ns105 ns106 ns107 ns108 ns109 ns110 ns111 ns112"

  • That's guite a list. And now if I test the map the result looks like the picture below :

 

  • And that's exactly what the customer wanted.

I hope this Blog post will help other people wha are struggeling with the same problem. If it does, please leave a comment below.

Published Thu, Mar 10 2011 8:53 AM by Patrick Wellink
Filed under: , ,

Comments

# re: Removing unwanted namespaces from a BizTalk Map

Saturday, April 02, 2011 10:55 AM by Fernando Pires

Hi Patrick

Here is another solution using a streaming approch! You would need to do this in a pipelinecomponent but as it is uses a streaming approch there should not be a performance issue.

1) First reference the Microsoft.BizTalk.Streaming dll

2) Second create the class bellow

using

Microsoft.BizTalk.Streaming;

using

System.IO;

using

System.Xml;

namespace

TestXmlFiles

{

public class XmlNamespaceRemoverStream :

XmlTranslatorStream

{

protected override void TranslateStartElement(

string prefix, string localName, string nsURI)

{

base.TranslateStartElement(null, localName, null);

}

protected override void TranslateAttribute()

{

if (this.m_reader.Prefix != "xmlns")

base.TranslateAttribute();

}

protected override void TranslateXmlDeclaration(string target, string value)

{

//This makes sure that the XmlDeclaration if any is not removed

this.m_writer.WriteProcessingInstruction(this.m_reader.Name, this.m_reader.Value);

}

public XmlNamespaceRemoverStream(Stream input)

: base(new XmlTextReader(input), Encoding.Default)

{ }

}

}

3) Third call it from your pipeline component.

public IBaseMessage Execute(IPipelineContext pContext, IBaseMessage

pInMsg)

{

IBaseMessagePart bodyPart = pInMsg.BodyPart;

Stream originalStream = bodyPart.GetOriginalDataStream();

if (originalStream != null)

{

XmlNamespaceRemoverStream rmstr = new XmlNamespaceRemoverStream(originalStream);

pInMsg.BodyPart.Data = rmstr;

}

return pInMsg

}

# re: Removing unwanted namespaces from a BizTalk Map

Wednesday, April 13, 2011 4:21 PM by Patrick Wellink

Yes, i know, But i needed to execute the map anyway, and by doing it this way, no extra coding is needed, and no extra processing is needed. All is done after the map is finished.

Leave a Comment

(required) 
(required) 
(optional)
(required) 
Please add 5 and 4 and type the answer here: