/// <summary>
 /// Creates an TXT tag using the Tag object info.
 /// </summary>
 /// <param name="aBuff">where to put tag</param>
 /// <param name="aTag">the tag</param>
 protected virtual void CreateTag(StringBuilder aBuff, Tag aTag)
 {
     if (aTag != null)
     {
         string lcDescription = null;
         try
         {
             lcDescription = aTag.GetDescription();
         }
         catch (MetadataException)
         {
             // Does not care here
         }
         string lcName = aTag.GetTagName();
         if (!this.DoUnknown && (lcName.ToLower().StartsWith("unknown") || lcDescription.ToLower().StartsWith("unknown")))
         {
             // No unKnown and is unKnown so do nothing
             return;
         }
         Normalize(aBuff, lcName, false); 
         aBuff.Append('=');
         Normalize(aBuff, lcDescription, false);
         aBuff.AppendLine();
     }
 }
        /// <summary>
        /// Creates an XML tag using the Tag object info.
        /// Examples :
        /// <pre>
        /// &lt;tag type="0x0044"&gt;
        ///   &lt;tagLabel&gt;White Balance&lt;/tagLabel&gt;
        ///   &lt;tagDescription>&lt;![CDATA[Very bright]]&gt;&lt;/tagDescription&gt;
        /// &lt;/tag&gt;
        /// <br/>
        /// &lt;tag type="0x0044"&gt;
        ///   &lt;tagLabel&gt;White Balance&lt;/tagLabel&gt;
        ///   &lt;tagDescription/&gt;
        /// &lt;/tag&gt;
        /// <br/>
        /// &lt;tag type="0x0044"&gt;
        ///   &lt;tagLabel&gt;White Balance&lt;/tagLabel&gt;
        ///   &lt;tagDescription/&gt;
        ///   &lt;tagError&gt;&lt;![CDATA[Oups something is wrong]]&gt;&lt;/tagError&gt;
        /// &lt;/tag&gt;
        /// </pre>
        /// </summary>
        /// <param name="aBuff">where to put tag</param>
        /// <param name="aTag">the tag</param>
        protected virtual void CreateTag(StringBuilder aBuff, Tag aTag)
        {
            if (aTag != null)
            {
                string lcDescription = null;
                string lcError = null;
                try
                {
                    lcDescription = aTag.GetDescription();
                }
                catch (MetadataException e)
                {
                    lcError = e.Message;
                }
                string lcName = aTag.GetTagName();
                string lcHexName = aTag.GetTagTypeHex();

                if (!this.DoUnknown && (lcName.ToLower().StartsWith("unknown") || lcDescription.ToLower().StartsWith("unknown")))
                {
                    // No unKnown and is unKnown so do nothing
                    return;
                }
                Open(aBuff, "tag", "type", lcHexName, true);

                Open(aBuff, "tagLabel", false);
                Normalize(aBuff, lcName, false); 
                Close(aBuff, "tagLabel", false);

                if (lcDescription != null && lcDescription.Length > 0)
                {
                    Open(aBuff, "tagDescription", false);
                    Normalize(aBuff, lcDescription, false);
                    Close(aBuff, "tagDescription", false);
                }
                else
                {
                    aBuff.Append("<tagDescription/>").AppendLine();
                }

                if (lcError != null)
                {
                    Open(aBuff, "tagError", false);
                    Normalize(aBuff, lcError, false); 
                    Close(aBuff, "tagError", false);
                }
                else
                {
                    // Does nothing if no error, this will limit the size of the XML 
                    // stream since 99% of tag will be fine
                    // aBuff.Append("<tagError/>");
                }
                Close(aBuff, "tag", true);
            }
        }
        /// <summary>
        /// Creates an XML tag using the Tag object info.
        /// Examples :
        /// <pre>
        /// &lt;tag type="0x0044"&gt;
        ///   &lt;tagLabel&gt;White Balance&lt;/tagLabel&gt;
        ///   &lt;tagDescription>&lt;![CDATA[Very bright]]&gt;&lt;/tagDescription&gt;
        /// &lt;/tag&gt;
        /// <br/>
        /// &lt;tag type="0x0044"&gt;
        ///   &lt;tagLabel&gt;White Balance&lt;/tagLabel&gt;
        ///   &lt;tagDescription/&gt;
        /// &lt;/tag&gt;
        /// <br/>
        /// &lt;tag type="0x0044"&gt;
        ///   &lt;tagLabel&gt;White Balance&lt;/tagLabel&gt;
        ///   &lt;tagDescription/&gt;
        ///   &lt;tagError&gt;&lt;![CDATA[Oups something is wrong]]&gt;&lt;/tagError&gt;
        /// &lt;/tag&gt;
        /// </pre>
        /// </summary>
        /// <param name="aBuff">where to put tag</param>
        /// <param name="aTag">the tag</param>
        protected virtual void CreateTag(StringBuilder aBuff, Tag aTag)
        {
            if (aTag != null)
            {
                string lcDescription = null;
                string lcError = null;
                try
                {
                    lcDescription = aTag.GetDescription();
                }
                catch (MetadataException e)
                {
                    lcError = e.Message;
                }
                string lcName = aTag.GetTagName();
                string lcHexName = aTag.GetTagTypeHex();
                object lcValue = aTag.GetTagValue();
                string lcValueStr = (lcValue != null) ? lcValue.ToString() : null;

                if (!this.DoUnknown
                    && (lcName.ToLower().StartsWith("unknown") || (lcDescription != null && lcDescription
                        .ToLower().StartsWith("unknown"))))
                {
                    // No unKnown and is unKnown so do nothing
                    return;
                }
                this.Open(aBuff, "tag", "typeHex", lcHexName,"type",aTag.GetTagType(), true);

                this.Open(aBuff, "tagLabel", false);
                this.Normalize(aBuff, lcName, UseCDData);
                this.Close(aBuff, "tagLabel", true);

                if (lcDescription != null && lcDescription.Trim().Length > 0)
                {
                    this.Open(aBuff, "tagDescription", false);
                    this.Normalize(aBuff, lcDescription, UseCDData);
                    this.Close(aBuff, "tagDescription", true);
                }
                else
                {
                    aBuff.Append("<tagDescription/>").AppendLine();
                }

                if (lcValueStr == null || lcValueStr.Trim().Length == 0
                    || "null".Equals(lcValueStr))
                {
                    aBuff.Append("<tagValue/>").AppendLine();
                }
                else
                {
                    this.Open(aBuff, "tagValue", "class", lcValue.GetType(), false);
                    if (lcValue.GetType().IsArray)
                    {
                        if (this.UseCDData)
                        {
                            aBuff.Append("<![CDATA[");
                        }

                        if (lcValue.GetType().Name.StartsWith("Int", StringComparison.OrdinalIgnoreCase))
                        {
                            // This is an array of int
                            int[] obj = (int[])lcValue;
                            for (int i = 0; i < obj.Length; i++)
                            {
                                aBuff.Append(obj[i]).Append(',');
                            }
                        }
                        else if (lcValue.GetType().Name.StartsWith("Byte", StringComparison.OrdinalIgnoreCase))
                        {
                            // This is an array of byte
                            byte[] obj = (byte[])lcValue;
                            for (int i = 0; i < obj.Length; i++)
                            {
                                aBuff.Append(obj[i]);
                                if (i + 1 != obj.Length)
                                {
                                    aBuff.Append(',');
                                }
                            }
                        }
                        else if (lcValue.GetType().Name.StartsWith("Rational", StringComparison.OrdinalIgnoreCase))
                        {
                            // This is an array of Rational
                            Rational[] obj = (Rational[])lcValue;
                            for (int i = 0; i < obj.Length; i++)
                            {
                                aBuff.Append(obj[i]);
                                if (i + 1 != obj.Length)
                                {
                                    aBuff.Append(',');
                                }
                            }
                        }
                        else if (lcValue.GetType().Name.StartsWith("string", StringComparison.OrdinalIgnoreCase))
                        {
                            // This is an array of string
                            string[] obj = (string[])lcValue;
                            for (int i = 0; i < obj.Length; i++)
                            {
                                aBuff.Append(obj[i]);
                                if (i + 1 != obj.Length)
                                {
                                    aBuff.Append(',');
                                }
                            }
                        }
                        if (this.UseCDData)
                        {
                            aBuff.Append("]]>");
                        }
                    }
                    else if (lcValue.GetType().Equals(typeof(DateTime)))
                    {
                        if (this.UseCDData)
                        {
                            aBuff.Append("<![CDATA[");
                        }
                        aBuff.Append(((DateTime)lcValue).ToString("dd/MM/yyyy HH:mm:ss"));
                        if (this.UseCDData)
                        {
                            aBuff.Append("]]>");
                        }
                    }
                    else
                    {
                        this.Normalize(aBuff, lcValueStr, UseCDData);
                    }
                    this.Close(aBuff, "tagValue", true);
                }

                if (lcError != null)
                {
                    lcError = lcError + " for typeHex=\"" + lcHexName + "\" type=\"" + aTag.GetTagType() + "\"";
                    this.Open(aBuff, "tagError", false);
                    this.Normalize(aBuff, lcError, UseCDData);
                    this.Close(aBuff, "tagError", true);
                }
                else
                {
                    // Does nothing if no error, this will limit the size of the XML
                    // stream since 99% of tag will be fine
                    // aBuff.Append("<tagError/>");
                }
                this.Close(aBuff, "tag", true);           
            }
        }