Geeks With Blogs
Alister's Occasional BizTalk & .NET Blog
| Home |

This is a very irritating issue which has taken me about two days to chase down - and all thanks to an apparently undocumented change between BizTalk 2006 and BizTalk 2006 R2

According to the documentation at MSDN (http://msdn.microsoft.com/en-us/library/aa561674.aspx), BizTalk maps should not preserve whitespace.

However, after a recent upgrade from 2006 to 2006 R2 our test platform started rejecting records which it had previously processed without complaint.  Initial analysis showed that it had suddenly started preserving whitespace in maps.

For example, in BizTalk 2006 (non-R2) when the element Field in the following XML:

<ns0:Root xmlns:ns0="http://BizTalk_Server_Project2.source1">   
  <Field> 
  </Field> 
</ns0:Root>

gets mapped to an element called Field1 in a slightly different schema:

<ns0:Root Field1="" xmlns:ns0="http://BizTalk_Server_Project2.destination> 

the whitespace between <Field> and </Field> is stripped away (as expected).

But after upgrading to R2, the behaviour mysteriously changes and the output is now:

<ns0:Root Field1="&#xD;&#xA;  " xmlns:ns0="http://BizTalk_Server_Project2.destination>

Eventually, after digging about in Reflector, I found out why.  In BizTalk 2006 (non-R2), the method Microsoft.BizTalk.ScalableTransformation.BTSXslTransform.DoStandardTransformation looks like this:

private void DoStandardTransform(Stream strm, XsltArgumentList args, Stream output, XmlResolver resolver)   
{  
    Trace.Tracer.TraceMessage(4, "LMT:Use Standard Transformation", new object[0]);  
    XPathDocument input = new XPathDocument(strm);  
    this.xform.Transform(input, args, output, resolver);  
    Trace.Tracer.TraceMessage(4, "LMT:Done with Standard Transformation", new object[0]);  

But in R2 it looks like this:

private void DoStandardTransform(Stream strm, XsltArgumentList args, Stream output, XmlResolver resolver)   
{  
    Trace.Tracer.TraceMessage(4, "LMT:Use Standard Transformation", new object[0]);  
    if (legacyWhitespaceBehavior)  
    {  
        this.xform.Transform(new XPathDocument(strm), args, output, resolver);  
    }  
    else
    {  
        this.xform.Transform(new XPathDocument(new XmlTextReader(strm), XmlSpace.Preserve), args, output, resolver);  
    }  
    Trace.Tracer.TraceMessage(4, "LMT:Done with Standard Transformation", new object[0]);  

Digging a little further, I found that legacyWhitespaceBehaviour gets set in the static constructor:

static BTSXslTransform()   
{  
    Transform_CLSID = new Guid("{917718A6-67E1-47c0-9267-2164A0DF632B}");  
    legacyWhitespaceBehavior = false;  
    defaultAutoSwitchThreshold = 0x100000;  
    int registryValue = Utils.GetRegistryValue("TransformThreshold", @"Software\Microsoft\BizTalk Server\3.0\Administration");  
    if (registryValue > 0)  
    {  
        defaultAutoSwitchThreshold = registryValue;  
    }  
    if (Utils.GetRegistryValue("LegacyWhitespace", @"Software\Microsoft\BizTalk Server\3.0\Administration") > 0)  
    {  
        legacyWhitespaceBehavior = true;  
    }  

And sure enough, by creating the registry key HKLM\Software\Microsoft\BizTalk Server\3.0\Administration\LegacyWhitespace and setting it to 1, I got the result I was expecting.

Googling for "biztalk legacywhitespace" returns no results, so this is apparently a completely undocumented feature  

Posted on Thursday, January 8, 2009 12:50 PM BizTalk , R2 , XSLT | Back to top


Comments on this post: Difference in whitespace preservation in maps between BizTalk 2006 and BizTalk 2006 R2

No comments posted yet.
Your comment:
 (will show your gravatar)


Copyright © Alister | Powered by: GeeksWithBlogs.net