private void GetXml(StringBuilder msg, object value, string key, ChoNullValueHandling nullValueHandling, string nsPrefix = null, bool isCDATA = false, bool emitDataType = false) { if (value is ChoDynamicObject) { msg.AppendFormat("{0}{1}", Environment.NewLine, ((ChoDynamicObject)value).GetXml(((ChoDynamicObject)value).NName, nullValueHandling, nsPrefix).Indent(1, " ")); } else { if (value != null) { if (value.GetType().IsSimple()) { if (isCDATA) { msg.AppendFormat("{0}{1}", Environment.NewLine, "<{0}><![CDATA[{1}]]></{0}>".FormatString(key, value).Indent(1, " ")); } else { msg.AppendFormat("{0}{1}", Environment.NewLine, "<{0}>{1}</{0}>".FormatString(key, value).Indent(1, " ")); } } else { key = value is IList?key.ToPlural() != key?key.ToPlural() : key.Length > 1 && key.EndsWith("s", StringComparison.InvariantCultureIgnoreCase) ? key : "{0}s".FormatString(key) : key; msg.AppendFormat("{0}{1}", Environment.NewLine, "<{0}>".FormatString(key).Indent(1, " ")); if (value is IList) { foreach (var collValue in ((IList)value).OfType <ChoDynamicObject>()) { msg.AppendFormat("{0}{1}", Environment.NewLine, collValue.GetXml(collValue.NName == DefaultName ? key.ToSingular() : collValue.NName, nullValueHandling, nsPrefix).Indent(2, " ")); } } else { msg.AppendFormat("{0}{1}", Environment.NewLine, ChoUtility.XmlSerialize(value).Indent(2, " ")); } msg.AppendFormat("{0}{1}", Environment.NewLine, "</{0}>".FormatString(key).Indent(1, " ")); } } else { switch (nullValueHandling) { case ChoNullValueHandling.Empty: msg.AppendFormat("{0}{1}", Environment.NewLine, @"<{0}/>".FormatString(key).Indent(1, " ")); break; case ChoNullValueHandling.Ignore: break; default: msg.AppendFormat("{0}{1}", Environment.NewLine, @"<{0} xsi:nil=""true"" xmlns:xsi=""{1}""/>".FormatString(key, ChoXmlSettings.XmlSchemaInstanceNamespace).Indent(1, " ")); break; } } } }
//public static bool SetFieldErrorMsg(this object target, string fieldName, string msg) //{ // PropertyInfo pi = null; // if (ChoType.HasProperty(target.GetType(), "FieldErrorMsg", out pi) // && !ChoType.IsReadOnlyMember(pi)) // ChoType.SetPropertyValue(target, pi, msg); // else // return false; // return true; //} //public static bool SetErrorMsg(this object target, string msg) //{ // //if (target is ChoRecord) // // ((ChoRecord)target).SetErrorMsg(msg); // //else // //{ // MethodInfo mi = null; // if (ChoType.HasMethod(target.GetType(), "SetErrorMsg", new Type[] { typeof(string) }, out mi)) // ChoType.SetPropertyValue(target, pi, msg); // else // return false; // //} // return true; //} //public static string GetErrorMsg(this object target) //{ // //if (target is ChoRecord) // // return ((ChoRecord)target).GetErrorMsg(); // //else // //{ // PropertyInfo pi = null; // if (ChoType.HasProperty(target.GetType(), "ErrorMsg", out pi)) // return ChoType.GetPropertyValue(target, pi).CastTo<string>(); // else // return null; // //} //} public static string GetXml(this object target, string tag = null) { if (target is ChoDynamicObject) { return(((ChoDynamicObject)target).GetXml()); } else { return(ChoUtility.XmlSerialize(target)); } }
public override IEnumerable <object> WriteTo(object writer, IEnumerable <object> records, Func <object, bool> predicate = null) { TextWriter sw = writer as TextWriter; ChoGuard.ArgumentNotNull(sw, "TextWriter"); if (records == null) { yield break; } CultureInfo prevCultureInfo = System.Threading.Thread.CurrentThread.CurrentCulture; System.Threading.Thread.CurrentThread.CurrentCulture = Configuration.Culture; _se = new Lazy <XmlSerializer>(() => Configuration.XmlSerializer == null ? null : Configuration.XmlSerializer); string recText = String.Empty; try { foreach (object record in records) { _index++; if (TraceSwitch.TraceVerbose) { if (record is IChoETLNameableObject) { ChoETLFramework.WriteLog(TraceSwitch.TraceVerbose, "Writing [{0}] object...".FormatString(((IChoETLNameableObject)record).Name)); } else { ChoETLFramework.WriteLog(TraceSwitch.TraceVerbose, "Writing [{0}] object...".FormatString(_index)); } } recText = String.Empty; if (predicate == null || predicate(record)) { //Discover and load Xml columns from first record if (!_configCheckDone) { if (record == null) { continue; } string[] fieldNames = null; Type recordType = ElementType == null?record.GetType() : ElementType; if (typeof(ICollection).IsAssignableFrom(recordType)) { recordType = recordType.GetEnumerableItemType().GetUnderlyingType(); } else { recordType = recordType.GetUnderlyingType(); } Configuration.IsDynamicObject = recordType.IsDynamicType(); if (!Configuration.IsDynamicObject) { if (recordType.IsSimple()) { Configuration.RecordType = typeof(ChoScalarObject <>).MakeGenericType(recordType); } else { Configuration.RecordType = recordType; } } if (Configuration.IsDynamicObject) { var dict = record.ToDynamicObject() as IDictionary <string, Object>; fieldNames = dict.Keys.ToArray(); } else { fieldNames = ChoTypeDescriptor.GetProperties <ChoXmlNodeRecordFieldAttribute>(Configuration.RecordType).Select(pd => pd.Name).ToArray(); if (fieldNames.Length == 0) { fieldNames = ChoType.GetProperties(Configuration.RecordType).Select(p => p.Name).ToArray(); } } Configuration.Validate(fieldNames); _configCheckDone = true; if (!RaiseBeginWrite(sw)) { yield break; } sw.Write("<{0}{1}>".FormatString(Configuration.RootName, GetNamespaceText())); } if (!RaiseBeforeRecordWrite(record, _index, ref recText)) { yield break; } if (recText == null) { continue; } try { if (!Configuration.UseXmlSerialization) { if ((Configuration.ObjectValidationMode & ChoObjectValidationMode.ObjectLevel) == ChoObjectValidationMode.ObjectLevel) { record.DoObjectLevelValidation(Configuration, Configuration.XmlRecordFieldConfigurations); } if (ToText(_index, record, out recText)) { if (!recText.IsNullOrEmpty()) { sw.Write("{1}{0}", recText, Configuration.EOLDelimiter); } if (!RaiseAfterRecordWrite(record, _index, recText)) { yield break; } } } else { if ((Configuration.ObjectValidationMode & ChoObjectValidationMode.Off) != ChoObjectValidationMode.Off) { record.DoObjectLevelValidation(Configuration, Configuration.XmlRecordFieldConfigurations); } if (record != null) { if (_se.Value != null) { _se.Value.Serialize(sw, record); } else { sw.Write("{1}{0}", ChoUtility.XmlSerialize(record).Indent(2, Configuration.IndentChar.ToString()), Configuration.EOLDelimiter); } if (!RaiseAfterRecordWrite(record, _index, null)) { yield break; } } } } //catch (ChoParserException) //{ // throw; //} catch (Exception ex) { ChoETLFramework.HandleException(ex); if (Configuration.ErrorMode == ChoErrorMode.IgnoreAndContinue) { ChoETLFramework.WriteLog(TraceSwitch.TraceVerbose, "Error [{0}] found. Ignoring record...".FormatString(ex.Message)); } else if (Configuration.ErrorMode == ChoErrorMode.ReportAndContinue) { if (!RaiseRecordWriteError(record, _index, recText, ex)) { throw; } else { ChoETLFramework.WriteLog(TraceSwitch.TraceVerbose, "Error [{0}] found. Ignoring record...".FormatString(ex.Message)); } } else { throw; } } } yield return(record); if (Configuration.NotifyAfter > 0 && _index % Configuration.NotifyAfter == 0) { if (RaisedRowsWritten(_index)) { ChoETLFramework.WriteLog(TraceSwitch.TraceVerbose, "Abort requested."); yield break; } } } } finally { System.Threading.Thread.CurrentThread.CurrentCulture = prevCultureInfo; } }
private bool ToText(long index, object rec, out string recText) { if (typeof(IChoScalarObject).IsAssignableFrom(Configuration.RecordType)) { rec = Activator.CreateInstance(Configuration.RecordType, rec); } recText = null; if (rec == null) { if (Configuration.NullValueHandling == ChoNullValueHandling.Ignore) { return(false); } else if (Configuration.NullValueHandling == ChoNullValueHandling.Default) { rec = Activator.CreateInstance(Configuration.RecordType); } else { recText = @"<{0} xsi:nil=""true"" />".FormatString(Configuration.NodeName ).Indent(Configuration.Indent * 1, Configuration.IndentChar.ToString()); return(true); } } StringBuilder msg = new StringBuilder(); object fieldValue = null; string fieldText = null; ChoXmlRecordFieldConfiguration fieldConfig = null; if (Configuration.ColumnCountStrict) { CheckColumnsStrict(rec); } //bool firstColumn = true; PropertyInfo pi = null; bool isElementClosed = false; bool isElementStart = false; foreach (KeyValuePair <string, ChoXmlRecordFieldConfiguration> kvp in GetOrderedKVP()) { fieldConfig = kvp.Value; fieldValue = null; fieldText = String.Empty; if (Configuration.PIDict != null) { Configuration.PIDict.TryGetValue(kvp.Key, out pi); } if (Configuration.ThrowAndStopOnMissingField) { if (Configuration.IsDynamicObject) { var dict = rec.ToDynamicObject() as IDictionary <string, Object>; if (!dict.ContainsKey(kvp.Key)) { throw new ChoMissingRecordFieldException("No matching property found in the object for '{0}' Xml node.".FormatString(fieldConfig.FieldName)); } } else { if (pi == null) { throw new ChoMissingRecordFieldException("No matching property found in the object for '{0}' Xml node.".FormatString(fieldConfig.FieldName)); } } } try { if (Configuration.IsDynamicObject) { IDictionary <string, Object> dict = rec.ToDynamicObject() as IDictionary <string, Object>; fieldValue = dict[kvp.Key]; // dict.GetValue(kvp.Key, Configuration.FileHeaderConfiguration.IgnoreCase, Configuration.Culture); if (kvp.Value.FieldType == null) { if (fieldValue == null) { kvp.Value.FieldType = typeof(string); } else { kvp.Value.FieldType = fieldValue.GetType(); } } } else { if (pi != null) { fieldValue = ChoType.GetPropertyValue(rec, pi); if (kvp.Value.FieldType == null) { kvp.Value.FieldType = pi.PropertyType; } } else { kvp.Value.FieldType = typeof(string); } } //Discover default value, use it if null if (fieldValue == null) { if (fieldConfig.IsDefaultValueSpecified) { fieldValue = fieldConfig.DefaultValue; } } if (!RaiseBeforeRecordFieldWrite(rec, index, kvp.Key, ref fieldValue)) { return(false); } if (fieldConfig.ValueConverter != null) { fieldValue = fieldConfig.ValueConverter(fieldValue); } else { rec.GetNConvertMemberValue(kvp.Key, kvp.Value, Configuration.Culture, ref fieldValue, true); } if ((Configuration.ObjectValidationMode & ChoObjectValidationMode.ObjectLevel) == ChoObjectValidationMode.MemberLevel) { rec.DoMemberLevelValidation(kvp.Key, kvp.Value, Configuration.ObjectValidationMode, fieldValue); } if (!RaiseAfterRecordFieldWrite(rec, index, kvp.Key, fieldValue)) { return(false); } } catch (ChoParserException) { throw; } catch (ChoMissingRecordFieldException) { if (Configuration.ThrowAndStopOnMissingField) { throw; } } catch (Exception ex) { ChoETLFramework.HandleException(ex); if (fieldConfig.ErrorMode == ChoErrorMode.ThrowAndStop) { throw; } try { if (Configuration.IsDynamicObject) { var dict = rec.ToDynamicObject() as IDictionary <string, Object>; if (dict.GetFallbackValue(kvp.Key, kvp.Value, Configuration.Culture, ref fieldValue)) { dict.DoMemberLevelValidation(kvp.Key, kvp.Value, Configuration.ObjectValidationMode, fieldValue); } else if (dict.GetDefaultValue(kvp.Key, kvp.Value, Configuration.Culture, ref fieldValue)) { dict.DoMemberLevelValidation(kvp.Key, kvp.Value, Configuration.ObjectValidationMode, fieldValue); } else { throw new ChoWriterException($"Failed to write '{fieldValue}' value for '{fieldConfig.FieldName}' member.", ex); } } else if (pi != null) { if (rec.GetFallbackValue(kvp.Key, kvp.Value, Configuration.Culture, ref fieldValue)) { rec.DoMemberLevelValidation(kvp.Key, kvp.Value, Configuration.ObjectValidationMode); } else if (rec.GetDefaultValue(kvp.Key, kvp.Value, Configuration.Culture, ref fieldValue)) { rec.DoMemberLevelValidation(kvp.Key, kvp.Value, Configuration.ObjectValidationMode, fieldValue); } else { throw new ChoWriterException($"Failed to write '{fieldValue}' value for '{fieldConfig.FieldName}' member.", ex); } } else { throw new ChoWriterException($"Failed to write '{fieldValue}' value for '{fieldConfig.FieldName}' member.", ex); } } catch (Exception innerEx) { if (ex == innerEx.InnerException) { if (fieldConfig.ErrorMode == ChoErrorMode.IgnoreAndContinue) { continue; } else { if (!RaiseRecordFieldWriteError(rec, index, kvp.Key, fieldText, ex)) { throw new ChoWriterException($"Failed to write '{fieldValue}' value of '{kvp.Key}' member.", ex); } } } else { throw new ChoWriterException("Failed to use '{0}' fallback value for '{1}' member.".FormatString(fieldValue, kvp.Key), innerEx); } } } if (fieldValue == null) { if (!fieldConfig.IsXmlAttribute && fieldConfig.IsNullable) { if (Configuration.RecordType == typeof(ChoScalarObject)) { if (!isElementStart) { msg.Append(@"<{0} xsi:nil=""true""".FormatString(Configuration.NodeName).Indent(Configuration.Indent, Configuration.IndentChar.ToString())); isElementStart = true; } if (!isElementClosed) { msg.AppendFormat(">{0}", Configuration.EOLDelimiter); isElementClosed = true; } } else { if (!isElementStart) { msg.Append("<{0}".FormatString(Configuration.NodeName).Indent(Configuration.Indent, Configuration.IndentChar.ToString())); isElementStart = true; } if (!isElementClosed) { msg.AppendFormat(">{0}", Configuration.EOLDelimiter); isElementClosed = true; } msg.Append(@"<{0} xsi:nil=""true"" />{1}".FormatString(fieldConfig.FieldName, Configuration.EOLDelimiter).Indent(Configuration.Indent * 2, Configuration.IndentChar.ToString())); } } else { if (Configuration.RecordType != typeof(ChoScalarObject)) { if (!isElementStart) { msg.Append("<{0}".FormatString(Configuration.NodeName).Indent(Configuration.Indent, Configuration.IndentChar.ToString())); isElementStart = true; } } //isElementClosed = true; fieldText = String.Empty; } } else { if (!isElementStart) { msg.Append("<{0}".FormatString(Configuration.NodeName).Indent(Configuration.Indent, Configuration.IndentChar.ToString())); isElementStart = true; } if (fieldValue.GetType().IsSimple()) { fieldText = fieldValue.ToString(); if (Configuration.RecordType == typeof(ChoScalarObject)) { if (fieldConfig.IsXmlAttribute) { msg.Append(@" {0}=""{1}""".FormatString(fieldConfig.FieldName, NormalizeFieldValue(kvp.Key, fieldText, kvp.Value.Size, kvp.Value.Truncate, kvp.Value.QuoteField, GetFieldValueJustification(kvp.Value.FieldValueJustification, kvp.Value.FieldType), GetFillChar(kvp.Value.FillChar, kvp.Value.FieldType), false))); } else { if (!isElementClosed) { msg.AppendFormat(">{0}", Configuration.EOLDelimiter); isElementClosed = true; } msg.Append("{0}{1}".FormatString( NormalizeFieldValue(kvp.Key, fieldText, kvp.Value.Size, kvp.Value.Truncate, kvp.Value.QuoteField, GetFieldValueJustification(kvp.Value.FieldValueJustification, kvp.Value.FieldType), GetFillChar(kvp.Value.FillChar, kvp.Value.FieldType), false), Configuration.EOLDelimiter).Indent(Configuration.Indent * 2, Configuration.IndentChar.ToString())); } } else if (fieldConfig.IsXmlAttribute) { msg.Append(@" {0}=""{1}""".FormatString(fieldConfig.FieldName, NormalizeFieldValue(kvp.Key, fieldText, kvp.Value.Size, kvp.Value.Truncate, kvp.Value.QuoteField, GetFieldValueJustification(kvp.Value.FieldValueJustification, kvp.Value.FieldType), GetFillChar(kvp.Value.FillChar, kvp.Value.FieldType), false))); } else { if (!isElementClosed) { msg.AppendFormat(">{0}", Configuration.EOLDelimiter); isElementClosed = true; } msg.Append("<{0}>{1}</{0}>{2}".FormatString(fieldConfig.FieldName, NormalizeFieldValue(kvp.Key, fieldText, kvp.Value.Size, kvp.Value.Truncate, kvp.Value.QuoteField, GetFieldValueJustification(kvp.Value.FieldValueJustification, kvp.Value.FieldType), GetFillChar(kvp.Value.FillChar, kvp.Value.FieldType), false), Configuration.EOLDelimiter).Indent(Configuration.Indent * 2, Configuration.IndentChar.ToString())); } } else { fieldText = ChoUtility.XmlSerialize(fieldValue); fieldText = _beginTagRegex.Replace(fieldText, delegate(Match thisMatch) { return("<{0}>".FormatString(fieldConfig.FieldName)); }); fieldText = _endTagRegex.Replace(fieldText, delegate(Match thisMatch) { return("</{0}>".FormatString(fieldConfig.FieldName)); }); if (!isElementClosed) { msg.AppendFormat(">{0}", Configuration.EOLDelimiter); isElementClosed = true; } msg.Append("{0}{1}".FormatString(fieldText, Configuration.EOLDelimiter).Indent(Configuration.Indent * 2, Configuration.IndentChar.ToString())); } } } if (!isElementClosed && msg.Length > 0) { msg.AppendFormat(">{0}", Configuration.EOLDelimiter); isElementClosed = true; } if (isElementStart) { msg.Append("</{0}>".FormatString(Configuration.NodeName).Indent(Configuration.Indent, Configuration.IndentChar.ToString())); isElementStart = false; } recText = msg.ToString(); return(true); }
public string GetXml(string tag = null) { if (tag.IsNullOrWhiteSpace()) { tag = NName; } bool hasAttrs = false; StringBuilder msg = new StringBuilder("<{0}".FormatString(tag)); foreach (string key in this.Keys.Where(k => k.StartsWith("@") && k != "@@Value")) { hasAttrs = true; msg.AppendFormat(@" {0}=""{1}""", key.Substring(1), this[key]); } if (ContainsKey("@@Value")) { if (hasAttrs) { msg.AppendFormat(">"); msg.AppendFormat("{0}{1}", Environment.NewLine, this["@@Value"].ToNString().Indent(1, " ")); msg.AppendFormat("{0}</{1}>", Environment.NewLine, tag); } else { msg.AppendFormat(">"); msg.AppendFormat("{0}", this["@@Value"].ToNString()); msg.AppendFormat("</{0}>", tag); } } else if (this.Keys.Any(k => !k.StartsWith("@"))) { object value = null; msg.AppendFormat(">"); foreach (string key in this.Keys.Where(k => !k.StartsWith("@"))) { value = this[key]; if (value is ChoDynamicObject) { msg.AppendFormat("{0}{1}", Environment.NewLine, ((ChoDynamicObject)value).GetXml(((ChoDynamicObject)value).NName).Indent(1, " ")); } else { if (value != null) { if (value.GetType().IsSimple()) { msg.AppendFormat("{0}{1}", Environment.NewLine, "<{0}>{1}</{0}>".FormatString(key, value).Indent(1, " ")); } else { msg.AppendFormat("{0}{1}", Environment.NewLine, "<{0}>".FormatString(key).Indent(1, " ")); if (value is IList) { foreach (var collValue in ((IList)value).OfType <ChoDynamicObject>()) { msg.AppendFormat("{0}{1}", Environment.NewLine, collValue.GetXml(collValue.NName == "dynamic" ? key.ToSingular() : collValue.NName).Indent(2, " ")); } } else { msg.AppendFormat("{0}{1}", Environment.NewLine, ChoUtility.XmlSerialize(value).Indent(2, " ")); } msg.AppendFormat("{0}{1}", Environment.NewLine, "</{0}>".FormatString(key).Indent(1, " ")); } } else { } } } msg.AppendFormat("{0}</{1}>", Environment.NewLine, tag); } else { msg.AppendFormat(" />"); } return(msg.ToString()); }