private ChoXmlWriter <T> WithField(string name, string xPath = null, Type fieldType = null, ChoFieldValueTrimOption fieldValueTrimOption = ChoFieldValueTrimOption.Trim, bool isXmlAttribute = false, bool isAnyXmlNode = false, string fieldName = null, Func <object, object> valueConverter = null, bool isNullable = false, object defaultValue = null, object fallbackValue = null, bool encodeValue = true, string fullyQualifiedMemberName = null, string formatText = null) { if (!name.IsNullOrEmpty()) { if (!_clearFields) { ClearFields(); Configuration.MapRecordFields(Configuration.RecordType); } string fnTrim = name.NTrim(); ChoXmlRecordFieldConfiguration fc = null; PropertyDescriptor pd = null; xPath = xPath.IsNullOrWhiteSpace() ? $"//{fnTrim}" : xPath; if (Configuration.XmlRecordFieldConfigurations.Any(o => o.Name == fnTrim)) { fc = Configuration.XmlRecordFieldConfigurations.Where(o => o.Name == fnTrim).First(); Configuration.XmlRecordFieldConfigurations.Remove(fc); } else { pd = ChoTypeDescriptor.GetNestedProperty(typeof(T), fullyQualifiedMemberName.IsNullOrWhiteSpace() ? name : fullyQualifiedMemberName); } var nfc = new ChoXmlRecordFieldConfiguration(fnTrim, xPath) { FieldType = fieldType, FieldValueTrimOption = fieldValueTrimOption, IsXmlAttribute = isXmlAttribute, FieldName = fieldName, ValueConverter = valueConverter, IsNullable = isNullable, DefaultValue = defaultValue, FallbackValue = fallbackValue, EncodeValue = encodeValue, FormatText = formatText, IsAnyXmlNode = isAnyXmlNode }; if (fullyQualifiedMemberName.IsNullOrWhiteSpace()) { nfc.PropertyDescriptor = fc != null ? fc.PropertyDescriptor : pd; nfc.DeclaringMember = fc != null ? fc.DeclaringMember : fullyQualifiedMemberName; } else { pd = ChoTypeDescriptor.GetNestedProperty(typeof(T), fullyQualifiedMemberName); nfc.PropertyDescriptor = pd; nfc.DeclaringMember = fullyQualifiedMemberName; } Configuration.XmlRecordFieldConfigurations.Add(nfc); } return(this); }
private string CleanFieldValue(ChoXmlRecordFieldConfiguration config, Type fieldType, string fieldValue, bool?encodeValue) { if (fieldValue == null) { return(fieldValue); } ChoFieldValueTrimOption fieldValueTrimOption = ChoFieldValueTrimOption.Trim; if (config.FieldValueTrimOption == null) { //if (fieldType == typeof(string)) // fieldValueTrimOption = ChoFieldValueTrimOption.None; } else { fieldValueTrimOption = config.FieldValueTrimOption.Value; } switch (fieldValueTrimOption) { case ChoFieldValueTrimOption.Trim: fieldValue = fieldValue.Trim(); break; case ChoFieldValueTrimOption.TrimStart: fieldValue = fieldValue.TrimStart(); break; case ChoFieldValueTrimOption.TrimEnd: fieldValue = fieldValue.TrimEnd(); break; } if (config.Size != null) { if (fieldValue.Length > config.Size.Value) { if (!config.Truncate) { throw new ChoParserException("Incorrect field value length found for '{0}' member [Expected: {1}, Actual: {2}].".FormatString(config.FieldName, config.Size.Value, fieldValue.Length)); } else { fieldValue = fieldValue.Substring(0, config.Size.Value); } } } if (encodeValue != null && !encodeValue.Value && fieldValue != null) { return(System.Net.WebUtility.HtmlEncode(fieldValue)); } return(System.Net.WebUtility.HtmlDecode(fieldValue)); }
public void Write(DataTable dt) { ChoGuard.ArgumentNotNull(dt, "DataTable"); if (Configuration.UseXmlSerialization) { Write(dt); return; } DataTable schemaTable = dt; dynamic expando = new ExpandoObject(); var expandoDic = (IDictionary <string, object>)expando; string rootName = dt.DataSet == null || dt.DataSet.DataSetName.IsNullOrWhiteSpace() ? "Root" : dt.DataSet.DataSetName; string elementName = dt.TableName.IsNullOrWhiteSpace() ? "XElement" : dt.TableName; if (Configuration.XPath.IsNullOrWhiteSpace()) { Configuration.XPath = "{0}/{1}".FormatString(rootName, elementName); } if (Configuration.XmlRecordFieldConfigurations.IsNullOrEmpty()) { string colName = null; Type colType = null; int startIndex = 0; int fieldLength = 0; foreach (DataColumn col in schemaTable.Columns) { colName = col.ColumnName; colType = col.DataType; //if (!colType.IsSimple()) continue; var obj = new ChoXmlRecordFieldConfiguration(colName, xPath: null); Configuration.XmlRecordFieldConfigurations.Add(obj); startIndex += fieldLength; } } foreach (DataRow row in dt.Rows) { expandoDic.Clear(); foreach (var fc in Configuration.XmlRecordFieldConfigurations) { expandoDic.Add(fc.Name, row[fc.Name]); } Write(expando); } }
public ChoXmlReader <T> WithFields(params string[] fieldsNames) { string fnTrim = null; if (!fieldsNames.IsNullOrEmpty()) { PropertyDescriptor pd = null; ChoXmlRecordFieldConfiguration fc = null; foreach (string fn in fieldsNames) { if (fn.IsNullOrEmpty()) { continue; } if (!_clearFields) { ClearFields(); Configuration.MapRecordFields(Configuration.RecordType); } fnTrim = fn.NTrim(); if (Configuration.XmlRecordFieldConfigurations.Any(o => o.Name == fnTrim)) { fc = Configuration.XmlRecordFieldConfigurations.Where(o => o.Name == fnTrim).First(); Configuration.XmlRecordFieldConfigurations.Remove(Configuration.XmlRecordFieldConfigurations.Where(o => o.Name == fnTrim).First()); } else { pd = ChoTypeDescriptor.GetProperty(typeof(T), fn); } var nfc = new ChoXmlRecordFieldConfiguration(fnTrim, $"/{fnTrim}"); nfc.PropertyDescriptor = fc != null ? fc.PropertyDescriptor : pd; nfc.DeclaringMember = fc != null ? fc.DeclaringMember : null; if (pd != null) { if (nfc.FieldType == null) { nfc.FieldType = pd.PropertyType; } } Configuration.XmlRecordFieldConfigurations.Add(nfc); } } return(this); }
public void Write(IDataReader dr) { ChoGuard.ArgumentNotNull(dr, "DataReader"); if (Configuration.UseXmlSerialization) { Write(dr); return; } DataTable schemaTable = dr.GetSchemaTable(); dynamic expando = new ExpandoObject(); var expandoDic = (IDictionary <string, object>)expando; //int ordinal = 0; if (Configuration.XmlRecordFieldConfigurations.IsNullOrEmpty()) { string colName = null; Type colType = null; int startIndex = 0; int fieldLength = 0; foreach (DataRow row in schemaTable.Rows) { colName = row["ColumnName"].CastTo <string>(); colType = row["DataType"] as Type; //if (!colType.IsSimple()) continue; var obj = new ChoXmlRecordFieldConfiguration(colName, xPath: null); Configuration.XmlRecordFieldConfigurations.Add(obj); startIndex += fieldLength; } } var ordinals = Configuration.XmlRecordFieldConfigurations.ToDictionary(c => c.Name, c => dr.HasColumn(c.Name) ? dr.GetOrdinal(c.Name) : -1); while (dr.Read()) { expandoDic.Clear(); foreach (var fc in ordinals) { expandoDic.Add(fc.Key, fc.Value == -1 ? null : dr[fc.Value]); } Write(expando); } }
private XmlAttributeOverrides GetXmlOverrides(ChoXmlRecordFieldConfiguration fieldConfig, Type fieldType = null) { if (fieldType == null) { return(null); } XmlAttributeOverrides overrides = null; var xattribs = new XmlAttributes(); var xroot = new XmlRootAttribute(fieldConfig.FieldName); xattribs.XmlRoot = xroot; overrides = new XmlAttributeOverrides(); fieldType = fieldType == null ? fieldConfig.FieldType : fieldType; overrides.Add(fieldType, xattribs); return(overrides); }
public void Write(IDataReader dr) { ChoGuard.ArgumentNotNull(dr, "DataReader"); DataTable schemaTable = dr.GetSchemaTable(); dynamic expando = new ExpandoObject(); var expandoDic = (IDictionary <string, object>)expando; //int ordinal = 0; if (Configuration.XmlRecordFieldConfigurations.IsNullOrEmpty()) { string colName = null; Type colType = null; int startIndex = 0; int fieldLength = 0; foreach (DataRow row in schemaTable.Rows) { colName = row["ColumnName"].CastTo <string>(); colType = row["DataType"] as Type; //if (!colType.IsSimple()) continue; var obj = new ChoXmlRecordFieldConfiguration(colName, xPath: null); Configuration.XmlRecordFieldConfigurations.Add(obj); startIndex += fieldLength; } } while (dr.Read()) { expandoDic.Clear(); foreach (var fc in Configuration.XmlRecordFieldConfigurations) { expandoDic.Add(fc.Name, dr[fc.Name]); } Write(expando); } }
private void DiscoverRecordFields(Type recordType) { if (!IsDynamicObject) { XmlRecordFieldConfigurations.Clear(); if (ChoTypeDescriptor.GetProperties(recordType).Where(pd => pd.Attributes.OfType <ChoXmlNodeRecordFieldAttribute>().Any()).Any()) { foreach (PropertyDescriptor pd in ChoTypeDescriptor.GetProperties(recordType).Where(pd => pd.Attributes.OfType <ChoXmlNodeRecordFieldAttribute>().Any())) { //if (!pd.PropertyType.IsSimple()) // throw new ChoRecordConfigurationException("Property '{0}' is not a simple type.".FormatString(pd.Name)); var obj = new ChoXmlRecordFieldConfiguration(pd.Name, pd.Attributes.OfType <ChoXmlNodeRecordFieldAttribute>().First()); if (obj.XPath.IsNullOrWhiteSpace()) { obj.XPath = $"//{obj.FieldName}|//@{obj.FieldName}"; } obj.FieldType = pd.PropertyType; XmlRecordFieldConfigurations.Add(obj); } } else { foreach (PropertyDescriptor pd in ChoTypeDescriptor.GetProperties(recordType)) { //if (!pd.PropertyType.IsSimple()) // throw new ChoRecordConfigurationException("Property '{0}' is not a simple type.".FormatString(pd.Name)); var obj = new ChoXmlRecordFieldConfiguration(pd.Name, $"//{pd.Name}|//@{pd.Name}"); obj.FieldType = pd.PropertyType; XmlRecordFieldConfigurations.Add(obj); } } } }
private bool FillRecord(object rec, Tuple <long, XElement> pair) { long lineNo; XElement node; lineNo = pair.Item1; node = pair.Item2; fXElements = null; fieldValue = null; fieldConfig = null; pi = null; xpn = node.CreateNavigator(Configuration.NamespaceManager.NameTable); ToDictionary(node); foreach (KeyValuePair <string, ChoXmlRecordFieldConfiguration> kvp in Configuration.RecordFieldConfigurationsDict) { fieldValue = null; fieldConfig = kvp.Value; if (Configuration.PIDict != null) { Configuration.PIDict.TryGetValue(kvp.Key, out pi); } if (fieldConfig.XPath == "text()") { if (Configuration.GetNameWithNamespace(node.Name) == fieldConfig.FieldName) { object value = node; if (!RaiseBeforeRecordFieldLoad(rec, pair.Item1, kvp.Key, ref value)) { continue; } if (fieldConfig.ValueConverter != null) { value = fieldConfig.ValueConverter(value); } fieldValue = value is XElement ? ((XElement)value).ToObjectFromXml(typeof(ChoDynamicObject)) : value; //fieldValue = value is XElement ? node.Value : value; } else if (Configuration.ColumnCountStrict) { throw new ChoParserException("Missing '{0}' xml node.".FormatString(fieldConfig.FieldName)); } } else { if (/*!fieldConfig.UseCache && */ !xDict.ContainsKey(fieldConfig.FieldName)) { xNodes.Clear(); foreach (XPathNavigator z in xpn.Select(fieldConfig.XPath, Configuration.NamespaceManager)) { xNodes.Add(z.UnderlyingObject); } object value = xNodes; if (!RaiseBeforeRecordFieldLoad(rec, pair.Item1, kvp.Key, ref value)) { continue; } if (fieldConfig.ValueConverter != null) { fieldValue = fieldConfig.ValueConverter(value); } else { //object[] xNodes = ((IEnumerable)node.XPathEvaluate(fieldConfig.XPath, Configuration.NamespaceManager)).OfType<object>().ToArray(); //continue; XAttribute[] fXAttributes = xNodes.OfType <XAttribute>().ToArray(); if (!fXAttributes.IsNullOrEmpty()) //fXAttribute != null) { //fieldValue = fXAttribute.Value; if (fieldConfig.FieldType == null) { if (fXAttributes.Length == 1) { if (fieldConfig.ItemConverter != null) { fieldValue = fieldConfig.ItemConverter(fXAttributes[0]); } else { fieldValue = fXAttributes[0].Value; } } else { List <object> arr = new List <object>(); foreach (var ele in fXAttributes) { if (fieldConfig.ItemConverter != null) { arr.Add(fieldConfig.ItemConverter(ele)); } else { arr.Add(ele.Value); } } fieldValue = arr.ToArray(); } } else if (fieldConfig.FieldType == typeof(string) || fieldConfig.FieldType.IsSimple()) { XAttribute fXElement = fXAttributes.FirstOrDefault(); if (fXElement != null) { if (fieldConfig.ItemConverter != null) { fieldValue = fieldConfig.ItemConverter(fXElement); } else { fieldValue = fXElement.Value; } } } else if (fieldConfig.FieldType.IsCollection()) { List <object> list = new List <object>(); Type itemType = fieldConfig.FieldType.GetItemType().GetUnderlyingType(); foreach (var ele in fXAttributes) { if (fieldConfig.ItemConverter != null) { list.Add(fieldConfig.ItemConverter(ele)); } else { if (itemType.IsSimple()) { list.Add(ChoConvert.ConvertTo(ele.Value, itemType)); } else { list.Add(ele.Value); } } } fieldValue = list.ToArray(); } else { XAttribute fXElement = fXAttributes.FirstOrDefault(); if (fXElement != null) { if (fieldConfig.ItemConverter != null) { fieldValue = fieldConfig.ItemConverter(fXElement); } else { fieldValue = fXElement.Value; } } } } else { fXElements = xNodes.OfType <XElement>().ToArray(); if (!fXElements.IsNullOrEmpty()) { if (fieldConfig.IsArray != null && fieldConfig.IsArray.Value) { List <object> list = new List <object>(); Type itemType = fieldConfig.FieldType != null?fieldConfig.FieldType.GetItemType().GetUnderlyingType() : typeof(ChoDynamicObject); foreach (var ele in fXElements) { if (fieldConfig.ItemConverter != null) { list.Add(fieldConfig.ItemConverter(ele)); } else { if (itemType.IsSimple()) { list.Add(ChoConvert.ConvertTo(ele.Value, itemType)); } else { if (itemType == typeof(ChoDynamicObject)) { list.Add(ele.ToDynamic()); } else { list.Add(ele.ToObjectFromXml(itemType, GetXmlOverrides(fieldConfig))); } } } } fieldValue = list.ToArray(); } else { if (fieldConfig.FieldType == null || fieldConfig.FieldType == typeof(object) || fieldConfig.FieldType.GetItemType() == typeof(object)) { if (fXElements.Length == 1) { if (fieldConfig.ItemConverter != null) { fieldValue = fieldConfig.ItemConverter(fXElements[0]); } else { fieldValue = fXElements[0].ToObjectFromXml(typeof(ChoDynamicObject)); } } else { List <object> arr = new List <object>(); foreach (var ele in fXElements) { if (fieldConfig.ItemConverter != null) { arr.Add(fieldConfig.ItemConverter(ele)); } else { arr.Add(ele.ToObjectFromXml(typeof(ChoDynamicObject)) as ChoDynamicObject); } } fieldValue = arr.ToArray(); } } else if (fieldConfig.FieldType == typeof(string) || fieldConfig.FieldType.IsSimple()) { XElement fXElement = fXElements.FirstOrDefault(); if (fXElement != null) { if (fieldConfig.ItemConverter != null) { fieldValue = fieldConfig.ItemConverter(fXElement); } else { fieldValue = fXElement.Value; } } } else if (fieldConfig.FieldType.IsCollection()) { List <object> list = new List <object>(); Type itemType = fieldConfig.FieldType.GetItemType().GetUnderlyingType(); //if (!itemType.IsSimple()) //{ // fXElements = fXElements.SelectMany(e => e.Elements()).ToArray(); //} foreach (var ele in fXElements) { if (fieldConfig.ItemConverter != null) { list.Add(fieldConfig.ItemConverter(ele)); } else { if (itemType.IsSimple()) { list.Add(ChoConvert.ConvertTo(ele.Value, itemType)); } else { list.Add(ele.ToObjectFromXml(itemType, null)); } } } fieldValue = list.ToArray(); } else { XElement fXElement = fXElements.FirstOrDefault(); //.SelectMany(e => e.Elements()).FirstOrDefault(); if (fXElement != null) { if (fieldConfig.ItemConverter != null) { fieldValue = fieldConfig.ItemConverter(fXElement); } else { fieldValue = fXElement.ToObjectFromXml(fieldConfig.FieldType, null); } } } } } else { XText[] xTexts = xNodes.OfType <XText>().ToArray(); if (!xTexts.IsNullOrEmpty()) { if (fieldConfig.FieldType == null) { if (xTexts.Length == 1) { if (fieldConfig.ItemConverter != null) { fieldValue = fieldConfig.ItemConverter(xTexts[0]); } else { fieldValue = xTexts[0].Value; } } else { List <object> arr = new List <object>(); foreach (var ele in xTexts) { if (fieldConfig.ItemConverter != null) { arr.Add(fieldConfig.ItemConverter(ele)); } else { arr.Add(ele.Value); } } fieldValue = arr.ToArray(); } } else if (fieldConfig.FieldType == typeof(string) || fieldConfig.FieldType.IsSimple()) { XText fXElement = xTexts.FirstOrDefault(); if (fXElement != null) { if (fieldConfig.ItemConverter != null) { fieldValue = fieldConfig.ItemConverter(fXElement); } else { fieldValue = fXElement.Value; } } } else if (fieldConfig.FieldType.IsCollection()) { List <object> list = new List <object>(); Type itemType = fieldConfig.FieldType.GetItemType().GetUnderlyingType(); foreach (var ele in xTexts) { if (fieldConfig.ItemConverter != null) { list.Add(fieldConfig.ItemConverter(ele)); } else { if (itemType.IsSimple()) { list.Add(ChoConvert.ConvertTo(ele.Value, itemType)); } else { list.Add(ele.Value); } } } fieldValue = list.ToArray(); } else { XText fXElement = xTexts.FirstOrDefault(); if (fXElement != null) { if (fieldConfig.ItemConverter != null) { fieldValue = fieldConfig.ItemConverter(fXElement); } else { fieldValue = fXElement.Value; } } } } else if (Configuration.ColumnCountStrict) { throw new ChoParserException("Missing '{0}' xml node.".FormatString(fieldConfig.FieldName)); } } } } } else { if (xDict[fieldConfig.FieldName].Count == 1) { fieldValue = xDict[fieldConfig.FieldName][0]; } else { fieldValue = xDict[fieldConfig.FieldName]; } if (!RaiseBeforeRecordFieldLoad(rec, pair.Item1, kvp.Key, ref fieldValue)) { continue; } if (fieldConfig.ValueConverter != null) { fieldValue = fieldConfig.ValueConverter(fieldValue); } } } if (Configuration.IsDynamicObject) { if (fieldValue != null && kvp.Value.FieldType == null && lineNo == 1) { kvp.Value.FieldType = fieldValue is ICollection?fieldValue.GetType() : fieldValue.GetType().IsSimple() ? DiscoverFieldType(fieldValue as string) : null; } } else { if (pi != null) { kvp.Value.FieldType = pi.PropertyType; } else { kvp.Value.FieldType = typeof(string); } } if (fieldValue is string) { fieldValue = CleanFieldValue(fieldConfig, kvp.Value.FieldType, fieldValue as string, kvp.Value.EncodeValue); } try { bool ignoreFieldValue = fieldConfig.IgnoreFieldValue(fieldValue); if (ignoreFieldValue) { fieldValue = fieldConfig.IsDefaultValueSpecified ? fieldConfig.DefaultValue : null; } if (Configuration.IsDynamicObject) { var dict = rec as IDictionary <string, Object>; if (!fieldConfig.IsArray.CastTo <bool>()) { dict.ConvertNSetMemberValue(kvp.Key, kvp.Value, ref fieldValue, Configuration.Culture); } else { dict[kvp.Key] = fieldValue; } if ((Configuration.ObjectValidationMode & ChoObjectValidationMode.MemberLevel) == ChoObjectValidationMode.MemberLevel) { dict.DoMemberLevelValidation(kvp.Key, kvp.Value, Configuration.ObjectValidationMode); } } else { if (pi != null) { rec.ConvertNSetMemberValue(kvp.Key, kvp.Value, ref fieldValue, Configuration.Culture); } else { throw new ChoMissingRecordFieldException("Missing '{0}' property in {1} type.".FormatString(kvp.Key, ChoType.GetTypeName(rec))); } if ((Configuration.ObjectValidationMode & ChoObjectValidationMode.MemberLevel) == ChoObjectValidationMode.MemberLevel) { rec.DoMemberLevelValidation(kvp.Key, kvp.Value, Configuration.ObjectValidationMode); } } if (!RaiseAfterRecordFieldLoad(rec, pair.Item1, kvp.Key, fieldValue)) { return(false); } } catch (ChoParserException) { Reader.IsValid = false; throw; } catch (ChoMissingRecordFieldException) { Reader.IsValid = false; if (Configuration.ThrowAndStopOnMissingField) { throw; } } catch (Exception ex) { Reader.IsValid = false; ChoETLFramework.HandleException(ref ex); if (fieldConfig.ErrorMode == ChoErrorMode.ThrowAndStop) { throw; } try { if (Configuration.IsDynamicObject) { var dict = rec as IDictionary <string, Object>; if (dict.SetFallbackValue(kvp.Key, kvp.Value, Configuration.Culture, ref fieldValue)) { dict.DoMemberLevelValidation(kvp.Key, kvp.Value, Configuration.ObjectValidationMode); } else if (dict.SetDefaultValue(kvp.Key, kvp.Value, Configuration.Culture)) { dict.DoMemberLevelValidation(kvp.Key, kvp.Value, Configuration.ObjectValidationMode); } else { throw new ChoReaderException($"Failed to parse '{fieldValue}' value for '{fieldConfig.FieldName}' field.", ex); } } else if (pi != null) { if (rec.SetFallbackValue(kvp.Key, kvp.Value, Configuration.Culture)) { rec.DoMemberLevelValidation(kvp.Key, kvp.Value, Configuration.ObjectValidationMode); } else if (rec.SetDefaultValue(kvp.Key, kvp.Value, Configuration.Culture)) { rec.DoMemberLevelValidation(kvp.Key, kvp.Value, Configuration.ObjectValidationMode); } else { throw new ChoReaderException($"Failed to parse '{fieldValue}' value for '{fieldConfig.FieldName}' field.", ex); } } else { throw new ChoReaderException($"Failed to parse '{fieldValue}' value for '{fieldConfig.FieldName}' field.", ex); } } catch (Exception innerEx) { if (ex == innerEx.InnerException) { if (fieldConfig.ErrorMode == ChoErrorMode.IgnoreAndContinue) { continue; } else { if (!RaiseRecordFieldLoadError(rec, pair.Item1, kvp.Key, fieldValue, ex)) { throw new ChoReaderException($"Failed to parse '{fieldValue}' value for '{fieldConfig.FieldName}' field.", ex); } } } else { throw new ChoReaderException("Failed to assign '{0}' fallback value to '{1}' field.".FormatString(fieldValue, fieldConfig.FieldName), innerEx); } } } } return(true); }
public override void Validate(object state) { base.Validate(state); //if (XPath.IsNull()) // throw new ChoRecordConfigurationException("XPath can't be null or whitespace."); if (XPath.IsNullOrWhiteSpace()) { if (!IsDynamicObject && (RecordType.IsGenericType && RecordType.GetGenericTypeDefinition() == typeof(KeyValuePair <,>))) { NodeName = NodeName.IsNullOrWhiteSpace() ? "KeyValuePair" : NodeName; RootName = RootName.IsNullOrWhiteSpace() ? "KeyValuePairs" : RootName; } else if (!IsDynamicObject && !typeof(IChoScalarObject).IsAssignableFrom(RecordType)) { NodeName = NodeName.IsNullOrWhiteSpace() ? RecordType.Name : NodeName; RootName = RootName.IsNullOrWhiteSpace() ? NodeName.ToPlural() : RootName; } } else { RootName = RootName.IsNullOrWhiteSpace() ? XPath.SplitNTrim("/").Where(t => !t.IsNullOrWhiteSpace() && t.NTrim() != "." && t.NTrim() != ".." && t.NTrim() != "*").FirstOrDefault() : RootName; NodeName = NodeName.IsNullOrWhiteSpace() ? XPath.SplitNTrim("/").Where(t => !t.IsNullOrWhiteSpace() && t.NTrim() != "." && t.NTrim() != ".." && t.NTrim() != "*").Skip(1).FirstOrDefault() : NodeName; } string rootName = null; string nodeName = null; ChoXmlDocumentRootAttribute da = TypeDescriptor.GetAttributes(RecordType).OfType <ChoXmlDocumentRootAttribute>().FirstOrDefault(); if (da != null) { rootName = da.Name; } else { XmlRootAttribute ra = TypeDescriptor.GetAttributes(RecordType).OfType <XmlRootAttribute>().FirstOrDefault(); if (ra != null) { nodeName = ra.ElementName; } } RootName = RootName.IsNullOrWhiteSpace() && !rootName.IsNullOrWhiteSpace() ? rootName : RootName; NodeName = NodeName.IsNullOrWhiteSpace() && !nodeName.IsNullOrWhiteSpace() ? nodeName : NodeName; RootName = RootName.IsNullOrWhiteSpace() && !NodeName.IsNullOrWhiteSpace() ? NodeName.ToPlural() : RootName; if (!RootName.IsNullOrWhiteSpace() && RootName.ToSingular() != RootName) { NodeName = NodeName.IsNullOrWhiteSpace() && !RootName.IsNullOrWhiteSpace() ? RootName.ToSingular() : NodeName; } if (RootName.IsNullOrWhiteSpace()) { RootName = "Root"; } if (NodeName.IsNullOrWhiteSpace()) { NodeName = "XElement"; } //Encode Root and node names RootName = System.Net.WebUtility.HtmlEncode(RootName); NodeName = System.Net.WebUtility.HtmlEncode(NodeName); string[] fieldNames = null; XElement xpr = null; if (state is Tuple <long, XElement> ) { xpr = ((Tuple <long, XElement>)state).Item2; } else { fieldNames = state as string[]; } if (AutoDiscoverColumns && XmlRecordFieldConfigurations.Count == 0) { if (RecordType != null && !IsDynamicObject && ChoTypeDescriptor.GetProperties(RecordType).Where(pd => pd.Attributes.OfType <ChoXmlNodeRecordFieldAttribute>().Any()).Any()) { DiscoverRecordFields(RecordType); } else if (xpr != null) { XmlRecordFieldConfigurations.AddRange(DiscoverRecordFieldsFromXElement(xpr)); } else if (!fieldNames.IsNullOrEmpty()) { foreach (string fn in fieldNames) { if (IgnoredFields.Contains(fn)) { continue; } if (fn.StartsWith("_")) { string fn1 = fn.Substring(1); var obj = new ChoXmlRecordFieldConfiguration(fn, xPath: $"./{fn1}"); obj.FieldName = fn1; obj.IsXmlAttribute = true; XmlRecordFieldConfigurations.Add(obj); } else if (fn.EndsWith("_")) { string fn1 = fn.Substring(0, fn.Length - 1); var obj = new ChoXmlRecordFieldConfiguration(fn, xPath: $"./{fn1}"); obj.FieldName = fn1; obj.IsXmlCDATA = true; XmlRecordFieldConfigurations.Add(obj); } else { var obj = new ChoXmlRecordFieldConfiguration(fn, xPath: $"./{fn}"); XmlRecordFieldConfigurations.Add(obj); } } } } else { IsComplexXPathUsed = false; foreach (var fc in XmlRecordFieldConfigurations) { if (fc.IsArray == null) { fc.IsArray = typeof(ICollection).IsAssignableFrom(fc.FieldType); } if (fc.FieldName.IsNullOrWhiteSpace()) { fc.FieldName = fc.Name; } if (fc.XPath.IsNullOrWhiteSpace()) { fc.XPath = $"/{fc.FieldName}|/@{fc.FieldName}"; } else { if (fc.XPath == fc.FieldName || fc.XPath == $"/{fc.FieldName}" || fc.XPath == $"/{fc.FieldName}" || fc.XPath == $"/{fc.FieldName}" || fc.XPath == $"/@{fc.FieldName}" || fc.XPath == $"/@{fc.FieldName}" || fc.XPath == $"/@{fc.FieldName}" ) { } else { IsComplexXPathUsed = true; fc.UseCache = false; } } } } if (XmlRecordFieldConfigurations.Count <= 0) { throw new ChoRecordConfigurationException("No record fields specified."); } //Validate each record field foreach (var fieldConfig in XmlRecordFieldConfigurations) { fieldConfig.Validate(this); } //Check field position for duplicate string[] dupFields = XmlRecordFieldConfigurations.GroupBy(i => i.Name) .Where(g => g.Count() > 1) .Select(g => g.Key).ToArray(); if (dupFields.Length > 0) { throw new ChoRecordConfigurationException("Duplicate field(s) [Name(s): {0}] found.".FormatString(String.Join(",", dupFields))); } PIDict = new Dictionary <string, System.Reflection.PropertyInfo>(); PDDict = new Dictionary <string, PropertyDescriptor>(); foreach (var fc in XmlRecordFieldConfigurations) { var pd1 = fc.DeclaringMember.IsNullOrWhiteSpace() ? ChoTypeDescriptor.GetProperty(RecordType, fc.Name) : ChoTypeDescriptor.GetProperty(RecordType, fc.DeclaringMember); if (pd1 != null) { fc.PropertyDescriptor = pd1; } if (fc.PropertyDescriptor == null) { fc.PropertyDescriptor = TypeDescriptor.GetProperties(RecordType).AsTypedEnumerable <PropertyDescriptor>().Where(pd => pd.Name == fc.Name).FirstOrDefault(); } if (fc.PropertyDescriptor == null) { continue; } PIDict.Add(fc.Name, fc.PropertyDescriptor.ComponentType.GetProperty(fc.PropertyDescriptor.Name)); PDDict.Add(fc.Name, fc.PropertyDescriptor); } RecordFieldConfigurationsDict = XmlRecordFieldConfigurations.OrderBy(c => c.IsXmlAttribute).Where(i => !i.Name.IsNullOrWhiteSpace()).ToDictionary(i => i.Name); if (XmlRecordFieldConfigurations.Where(e => e.IsNullable).Any() || NullValueHandling == ChoNullValueHandling.Default) { if (NamespaceManager != null) { if (!NamespaceManager.HasNamespace("xsi")) { NamespaceManager.AddNamespace("xsi", ChoXmlSettings.XmlSchemaInstanceNamespace); } if (!NamespaceManager.HasNamespace("xsd")) { NamespaceManager.AddNamespace("xsd", ChoXmlSettings.XmlSchemaNamespace); } } } LoadNCacheMembers(XmlRecordFieldConfigurations); }
private void DiscoverRecordFields(Type recordType, string declaringMember, bool optIn = false) { if (recordType == null) { return; } if (!recordType.IsDynamicType()) { IsComplexXPathUsed = false; Type pt = null; if (optIn) //ChoTypeDescriptor.GetProperties(recordType).Where(pd => pd.Attributes.OfType<ChoXmlNodeRecordFieldAttribute>().Any()).Any()) { foreach (PropertyDescriptor pd in ChoTypeDescriptor.GetProperties(recordType)) { pt = pd.PropertyType.GetUnderlyingType(); var fa = pd.Attributes.OfType <ChoXmlNodeRecordFieldAttribute>().FirstOrDefault(); bool optIn1 = fa == null || fa.UseXmlSerialization ? optIn : ChoTypeDescriptor.GetProperties(pt).Where(pd1 => pd1.Attributes.OfType <ChoXmlNodeRecordFieldAttribute>().Any()).Any(); if (false) //optIn1 && !pt.IsSimple() && !typeof(IEnumerable).IsAssignableFrom(pt)) { DiscoverRecordFields(pt, declaringMember == null ? pd.Name : "{0}.{1}".FormatString(declaringMember, pd.Name), optIn1); } else if (pd.Attributes.OfType <ChoXmlNodeRecordFieldAttribute>().Any()) { bool useCache = true; string xpath = null; ChoXmlNodeRecordFieldAttribute attr = ChoTypeDescriptor.GetPropetyAttribute <ChoXmlNodeRecordFieldAttribute>(pd); if (attr.XPath.IsNullOrEmpty()) { if (!attr.FieldName.IsNullOrWhiteSpace()) { attr.XPath = $"/{attr.FieldName}|/@{attr.FieldName}"; } else { attr.XPath = xpath = $"/{pd.Name}|/@{pd.Name}"; } IsComplexXPathUsed = true; } else { useCache = false; } var obj = new ChoXmlRecordFieldConfiguration(pd.Name, attr, pd.Attributes.OfType <Attribute>().ToArray()); obj.FieldType = pt; obj.PropertyDescriptor = pd; obj.DeclaringMember = declaringMember == null ? null : "{0}.{1}".FormatString(declaringMember, pd.Name); obj.UseCache = useCache; if (obj.XPath.IsNullOrWhiteSpace()) { if (!obj.FieldName.IsNullOrWhiteSpace()) { obj.XPath = $"/{obj.FieldName}|/@{obj.FieldName}"; } else { obj.XPath = $"/{obj.Name}|/@{obj.Name}"; } } obj.FieldType = pd.PropertyType.GetUnderlyingType(); if (!XmlRecordFieldConfigurations.Any(c => c.Name == pd.Name)) { XmlRecordFieldConfigurations.Add(obj); } } } } else { foreach (PropertyDescriptor pd in ChoTypeDescriptor.GetProperties(recordType)) { XmlIgnoreAttribute xiAttr = pd.Attributes.OfType <XmlIgnoreAttribute>().FirstOrDefault(); if (xiAttr != null) { continue; } pt = pd.PropertyType.GetUnderlyingType(); if (false) //pt != typeof(object) && !pt.IsSimple() && !typeof(IEnumerable).IsAssignableFrom(pt)) { DiscoverRecordFields(pt, declaringMember == null ? pd.Name : "{0}.{1}".FormatString(declaringMember, pd.Name), optIn); } else { var obj = new ChoXmlRecordFieldConfiguration(pd.Name, $"/{pd.Name}|/@{pd.Name}"); obj.FieldType = pt; obj.PropertyDescriptor = pd; obj.DeclaringMember = declaringMember == null ? null : "{0}.{1}".FormatString(declaringMember, pd.Name); StringLengthAttribute slAttr = pd.Attributes.OfType <StringLengthAttribute>().FirstOrDefault(); if (slAttr != null && slAttr.MaximumLength > 0) { obj.Size = slAttr.MaximumLength; } XmlElementAttribute xAttr = pd.Attributes.OfType <XmlElementAttribute>().FirstOrDefault(); if (xAttr != null && !xAttr.ElementName.IsNullOrWhiteSpace()) { obj.FieldName = xAttr.ElementName; } else { XmlAttributeAttribute xaAttr = pd.Attributes.OfType <XmlAttributeAttribute>().FirstOrDefault(); if (xAttr != null && !xaAttr.AttributeName.IsNullOrWhiteSpace()) { obj.FieldName = xaAttr.AttributeName; } else { DisplayNameAttribute dnAttr = pd.Attributes.OfType <DisplayNameAttribute>().FirstOrDefault(); if (dnAttr != null && !dnAttr.DisplayName.IsNullOrWhiteSpace()) { obj.FieldName = dnAttr.DisplayName.Trim(); } else { DisplayAttribute dpAttr = pd.Attributes.OfType <DisplayAttribute>().FirstOrDefault(); if (dpAttr != null) { if (!dpAttr.ShortName.IsNullOrWhiteSpace()) { obj.FieldName = dpAttr.ShortName; } else if (!dpAttr.Name.IsNullOrWhiteSpace()) { obj.FieldName = dpAttr.Name; } } } } } DisplayFormatAttribute dfAttr = pd.Attributes.OfType <DisplayFormatAttribute>().FirstOrDefault(); if (dfAttr != null && !dfAttr.DataFormatString.IsNullOrWhiteSpace()) { obj.FormatText = dfAttr.DataFormatString; } if (dfAttr != null && !dfAttr.NullDisplayText.IsNullOrWhiteSpace()) { obj.NullValue = dfAttr.NullDisplayText; } if (!XmlRecordFieldConfigurations.Any(c => c.Name == pd.Name)) { XmlRecordFieldConfigurations.Add(obj); } } } } } }
public override void Validate(object state) { base.Validate(state); //if (XPath.IsNull()) // throw new ChoRecordConfigurationException("XPath can't be null or whitespace."); if (XPath.IsNullOrWhiteSpace()) { if (!IsDynamicObject && (RecordType.IsGenericType && RecordType.GetGenericTypeDefinition() == typeof(KeyValuePair <,>))) { NodeName = NodeName.IsNullOrWhiteSpace() ? "KeyValuePair" : NodeName; RootName = RootName.IsNullOrWhiteSpace() ? "KeyValuePairs" : RootName; } else if (!IsDynamicObject && !typeof(IChoScalarObject).IsAssignableFrom(RecordType)) { NodeName = NodeName.IsNullOrWhiteSpace() ? RecordType.Name : NodeName; RootName = RootName.IsNullOrWhiteSpace() ? NodeName.ToPlural() : NodeName; } } else { RootName = RootName.IsNullOrWhiteSpace() ? XPath.SplitNTrim("/").Where(t => !t.IsNullOrWhiteSpace() && t.NTrim() != "." && t.NTrim() != ".." && t.NTrim() != "*").FirstOrDefault() : RootName; NodeName = NodeName.IsNullOrWhiteSpace() ? XPath.SplitNTrim("/").Where(t => !t.IsNullOrWhiteSpace() && t.NTrim() != "." && t.NTrim() != ".." && t.NTrim() != "*").Skip(1).FirstOrDefault() : NodeName; } string rootName = null; string nodeName = null; ChoXmlDocumentRootAttribute da = TypeDescriptor.GetAttributes(RecordType).OfType <ChoXmlDocumentRootAttribute>().FirstOrDefault(); if (da != null) { rootName = da.Name; } else { XmlRootAttribute ra = TypeDescriptor.GetAttributes(RecordType).OfType <XmlRootAttribute>().FirstOrDefault(); if (ra != null) { nodeName = ra.ElementName; } } RootName = RootName.IsNullOrWhiteSpace() && !rootName.IsNullOrWhiteSpace() ? rootName : RootName; NodeName = NodeName.IsNullOrWhiteSpace() && !nodeName.IsNullOrWhiteSpace() ? nodeName : NodeName; RootName = RootName.IsNullOrWhiteSpace() && !NodeName.IsNullOrWhiteSpace() ? NodeName.ToPlural() : RootName; if (!RootName.IsNullOrWhiteSpace() && RootName.ToSingular() != RootName) { NodeName = NodeName.IsNullOrWhiteSpace() && !RootName.IsNullOrWhiteSpace() ? RootName.ToSingular() : NodeName; } if (RootName.IsNullOrWhiteSpace()) { RootName = "Root"; } if (NodeName.IsNullOrWhiteSpace()) { NodeName = "XElement"; } //Encode Root and node names RootName = System.Net.WebUtility.HtmlEncode(RootName); NodeName = System.Net.WebUtility.HtmlEncode(NodeName); string[] fieldNames = null; XElement xpr = null; if (state is Tuple <long, XElement> ) { xpr = ((Tuple <long, XElement>)state).Item2; } else { fieldNames = state as string[]; } if (AutoDiscoverColumns && XmlRecordFieldConfigurations.Count == 0) { if (RecordType != null && !IsDynamicObject && ChoTypeDescriptor.GetProperties(RecordType).Where(pd => pd.Attributes.OfType <ChoXmlNodeRecordFieldAttribute>().Any()).Any()) { DiscoverRecordFields(RecordType); } else if (xpr != null) { IsComplexXPathUsed = false; ChoXmlNamespaceManager nsMgr = new ChoXmlNamespaceManager(NamespaceManager); Dictionary <string, ChoXmlRecordFieldConfiguration> dict = new Dictionary <string, ChoXmlRecordFieldConfiguration>(StringComparer.CurrentCultureIgnoreCase); string name = null; foreach (var attr in xpr.Attributes()) { if (!attr.IsValidAttribute(XmlSchemaNamespace, JSONSchemaNamespace)) { continue; } if (!IsInNamespace(xpr.Name, attr.Name)) { continue; } //if (!attr.Name.NamespaceName.IsNullOrWhiteSpace()) continue; name = GetNameWithNamespace(xpr.Name, attr.Name); if (!dict.ContainsKey(name)) { dict.Add(name, new ChoXmlRecordFieldConfiguration(attr.Name.LocalName, $"./@{name}") { FieldName = name }); // DefaultNamespace.IsNullOrWhiteSpace() ? $"//@{name}" : $"//@{DefaultNamespace}" + ":" + $"{name}") { IsXmlAttribute = true }); } else { throw new ChoRecordConfigurationException("Duplicate field(s) [Name(s): {0}] found.".FormatString(name)); } } bool hasElements = false; //var z = xpr.Elements().ToArray(); XElement ele = null; foreach (var kvp in xpr.Elements().GroupBy(e => e.Name.LocalName).Select(g => new { Name = g.Key, Value = g.ToArray() })) { if (kvp.Value.Length == 1) { ele = kvp.Value.First(); if (!IsInNamespace(ele.Name)) { continue; } name = GetNameWithNamespace(ele.Name); hasElements = true; if (!dict.ContainsKey(name)) { dict.Add(name, new ChoXmlRecordFieldConfiguration(ele.Name.LocalName, $"./{name}") { FieldName = name }); // DefaultNamespace.IsNullOrWhiteSpace() ? $"//{name}" : $"//{DefaultNamespace}" + ":" + $"{name}")); } else { if (dict[name].IsXmlAttribute) { throw new ChoRecordConfigurationException("Duplicate field(s) [Name(s): {0}] found.".FormatString(name)); } dict[name].IsArray = true; } } else if (kvp.Value.Length > 1) { ele = kvp.Value.First(); if (!IsInNamespace(ele.Name)) { continue; } name = GetNameWithNamespace(ele.Name); hasElements = true; if (!dict.ContainsKey(name)) { dict.Add(name, new ChoXmlRecordFieldConfiguration(xpr.Name.LocalName, $"./{name}") { FieldName = name }); // DefaultNamespace.IsNullOrWhiteSpace() ? $"//{name}" : $"//{DefaultNamespace}" + ":" + $"{name}")); } else { if (dict[name].IsXmlAttribute) { throw new ChoRecordConfigurationException("Duplicate field(s) [Name(s): {0}] found.".FormatString(name)); } dict[name].IsArray = true; } } } //foreach (var ele in xpr.Elements()) //{ // if (!IsInNamespace(ele.Name)) // continue; // name = GetNameWithNamespace(ele.Name); // hasElements = true; // if (!dict.ContainsKey(name)) // dict.Add(name, new ChoXmlRecordFieldConfiguration(ele.Name.LocalName, $"/{name}") { FieldName = name }); // DefaultNamespace.IsNullOrWhiteSpace() ? $"//{name}" : $"//{DefaultNamespace}" + ":" + $"{name}")); // else // { // if (dict[name].IsXmlAttribute) // throw new ChoRecordConfigurationException("Duplicate field(s) [Name(s): {0}] found.".FormatString(name)); // dict[name].IsArray = true; // } //} if (!hasElements) { if (IsInNamespace(xpr.Name)) { //name = xpr.Name.LocalName; name = GetNameWithNamespace(xpr.Name); dict.Add(name, new ChoXmlRecordFieldConfiguration(name, "text()") { FieldName = name }); } } foreach (ChoXmlRecordFieldConfiguration obj in dict.Values) { XmlRecordFieldConfigurations.Add(obj); } } else if (!fieldNames.IsNullOrEmpty()) { foreach (string fn in fieldNames) { if (fn.StartsWith("_")) { string fn1 = fn.Substring(1); var obj = new ChoXmlRecordFieldConfiguration(fn, xPath: $"./{fn1}"); obj.FieldName = fn1; obj.IsXmlAttribute = true; XmlRecordFieldConfigurations.Add(obj); } else if (fn.EndsWith("_")) { string fn1 = fn.Substring(0, fn.Length - 1); var obj = new ChoXmlRecordFieldConfiguration(fn, xPath: $"./{fn1}"); obj.FieldName = fn1; obj.IsXmlCDATA = true; XmlRecordFieldConfigurations.Add(obj); } else { var obj = new ChoXmlRecordFieldConfiguration(fn, xPath: $"./{fn}"); XmlRecordFieldConfigurations.Add(obj); } } } } else { IsComplexXPathUsed = false; foreach (var fc in XmlRecordFieldConfigurations) { if (fc.IsArray == null) { fc.IsArray = typeof(ICollection).IsAssignableFrom(fc.FieldType); } if (fc.FieldName.IsNullOrWhiteSpace()) { fc.FieldName = fc.Name; } if (fc.XPath.IsNullOrWhiteSpace()) { fc.XPath = $"./{fc.FieldName}|.//@{fc.FieldName}"; } else { if (fc.XPath == fc.FieldName || fc.XPath == $"./{fc.FieldName}" || fc.XPath == $"./{fc.FieldName}" || fc.XPath == $"./{fc.FieldName}" || fc.XPath == $"./@{fc.FieldName}" || fc.XPath == $"./@{fc.FieldName}" || fc.XPath == $"./@{fc.FieldName}" ) { } else { IsComplexXPathUsed = true; fc.UseCache = false; } } } } if (XmlRecordFieldConfigurations.Count <= 0) { throw new ChoRecordConfigurationException("No record fields specified."); } //Validate each record field foreach (var fieldConfig in XmlRecordFieldConfigurations) { fieldConfig.Validate(this); } //Check field position for duplicate string[] dupFields = XmlRecordFieldConfigurations.GroupBy(i => i.Name) .Where(g => g.Count() > 1) .Select(g => g.Key).ToArray(); if (dupFields.Length > 0) { throw new ChoRecordConfigurationException("Duplicate field(s) [Name(s): {0}] found.".FormatString(String.Join(",", dupFields))); } PIDict = new Dictionary <string, System.Reflection.PropertyInfo>(); PDDict = new Dictionary <string, PropertyDescriptor>(); foreach (var fc in XmlRecordFieldConfigurations) { if (fc.PropertyDescriptor == null) { fc.PropertyDescriptor = ChoTypeDescriptor.GetProperties(RecordType).Where(pd => pd.Name == fc.Name).FirstOrDefault(); } if (fc.PropertyDescriptor == null) { continue; } PIDict.Add(fc.PropertyDescriptor.Name, fc.PropertyDescriptor.ComponentType.GetProperty(fc.PropertyDescriptor.Name)); PDDict.Add(fc.PropertyDescriptor.Name, fc.PropertyDescriptor); } RecordFieldConfigurationsDict = XmlRecordFieldConfigurations.OrderBy(c => c.IsXmlAttribute).Where(i => !i.Name.IsNullOrWhiteSpace()).ToDictionary(i => i.Name); if (XmlRecordFieldConfigurations.Where(e => e.IsNullable).Any() || NullValueHandling == ChoNullValueHandling.Default) { if (NamespaceManager != null) { if (!NamespaceManager.HasNamespace("xsi")) { NamespaceManager.AddNamespace("xsi", ChoXmlSettings.XmlSchemaInstanceNamespace); } if (!NamespaceManager.HasNamespace("xsd")) { NamespaceManager.AddNamespace("xsd", ChoXmlSettings.XmlSchemaNamespace); } } } LoadNCacheMembers(XmlRecordFieldConfigurations); }
private bool FillRecord(object rec, Tuple <long, XElement> pair) { long lineNo; XElement node; lineNo = pair.Item1; node = pair.Item2; fXElements = null; fieldValue = null; fieldConfig = null; pi = null; xpn = node.CreateNavigator(Configuration.NamespaceManager.NameTable); ToDictionary(node); foreach (KeyValuePair <string, ChoXmlRecordFieldConfiguration> kvp in Configuration.RecordFieldConfigurationsDict) { fieldValue = null; fieldConfig = kvp.Value; if (Configuration.PIDict != null) { Configuration.PIDict.TryGetValue(kvp.Key, out pi); } if (fieldConfig.XPath == "text()") { if (Configuration.GetNameWithNamespace(node.Name) == fieldConfig.FieldName) { fieldValue = node.Value; } else if (Configuration.ColumnCountStrict) { throw new ChoParserException("Missing '{0}' xml node.".FormatString(fieldConfig.FieldName)); } } else { if (!fieldConfig.UseCache && !xDict.ContainsKey(fieldConfig.FieldName)) { xNodes.Clear(); foreach (XPathNavigator z in xpn.Select(fieldConfig.XPath, Configuration.NamespaceManager)) { xNodes.Add(z.UnderlyingObject); } //object[] xNodes = ((IEnumerable)node.XPathEvaluate(fieldConfig.XPath, Configuration.NamespaceManager)).OfType<object>().ToArray(); //continue; XAttribute fXAttribute = xNodes.OfType <XAttribute>().FirstOrDefault(); if (fXAttribute != null) { fieldValue = fXAttribute.Value; } else { fXElements = xNodes.OfType <XElement>().ToArray(); if (fXElements != null) { if (fieldConfig.IsCollection) { List <string> list = new List <string>(); foreach (var ele in fXElements) { list.Add(ele.Value); } fieldValue = list.ToArray(); } else { XElement fXElement = fXElements.FirstOrDefault(); if (fXElement != null) { fieldValue = fXElement.Value; } } } else if (Configuration.ColumnCountStrict) { throw new ChoParserException("Missing '{0}' xml node.".FormatString(fieldConfig.FieldName)); } } } else { if (xDict[fieldConfig.FieldName].Count == 1) { fieldValue = xDict[fieldConfig.FieldName][0]; } else { fieldValue = xDict[fieldConfig.FieldName]; } } } if (rec is ExpandoObject) { if (kvp.Value.FieldType == null) { kvp.Value.FieldType = fieldValue is ICollection ? typeof(string[]) : typeof(string); } } else { if (pi != null) { kvp.Value.FieldType = pi.PropertyType; } else { kvp.Value.FieldType = typeof(string); } } if (!(fieldValue is ICollection)) { fieldValue = CleanFieldValue(fieldConfig, kvp.Value.FieldType, fieldValue as string); } if (!RaiseBeforeRecordFieldLoad(rec, pair.Item1, kvp.Key, ref fieldValue)) { continue; } try { bool ignoreFieldValue = fieldConfig.IgnoreFieldValue(fieldValue); if (ignoreFieldValue) { fieldValue = fieldConfig.IsDefaultValueSpecified ? fieldConfig.DefaultValue : null; } if (Configuration.IsDynamicObject) { var dict = rec as IDictionary <string, Object>; dict.ConvertNSetMemberValue(kvp.Key, kvp.Value, ref fieldValue, Configuration.Culture); if ((Configuration.ObjectValidationMode & ChoObjectValidationMode.MemberLevel) == ChoObjectValidationMode.MemberLevel) { dict.DoMemberLevelValidation(kvp.Key, kvp.Value, Configuration.ObjectValidationMode); } } else { if (pi != null) { rec.ConvertNSetMemberValue(kvp.Key, kvp.Value, ref fieldValue, Configuration.Culture); } else { throw new ChoMissingRecordFieldException("Missing '{0}' property in {1} type.".FormatString(kvp.Key, ChoType.GetTypeName(rec))); } if ((Configuration.ObjectValidationMode & ChoObjectValidationMode.MemberLevel) == ChoObjectValidationMode.MemberLevel) { rec.DoMemberLevelValidation(kvp.Key, kvp.Value, Configuration.ObjectValidationMode); } } if (!RaiseAfterRecordFieldLoad(rec, pair.Item1, 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 as IDictionary <string, Object>; if (dict.SetFallbackValue(kvp.Key, kvp.Value, Configuration.Culture, ref fieldValue)) { dict.DoMemberLevelValidation(kvp.Key, kvp.Value, Configuration.ObjectValidationMode); } else if (dict.SetDefaultValue(kvp.Key, kvp.Value, Configuration.Culture)) { dict.DoMemberLevelValidation(kvp.Key, kvp.Value, Configuration.ObjectValidationMode); } else { throw new ChoReaderException($"Failed to parse '{fieldValue}' value for '{fieldConfig.FieldName}' field.", ex); } } else if (pi != null) { if (rec.SetFallbackValue(kvp.Key, kvp.Value, Configuration.Culture)) { rec.DoMemberLevelValidation(kvp.Key, kvp.Value, Configuration.ObjectValidationMode); } else if (rec.SetDefaultValue(kvp.Key, kvp.Value, Configuration.Culture)) { rec.DoMemberLevelValidation(kvp.Key, kvp.Value, Configuration.ObjectValidationMode); } else { throw new ChoReaderException($"Failed to parse '{fieldValue}' value for '{fieldConfig.FieldName}' field.", ex); } } else { throw new ChoReaderException($"Failed to parse '{fieldValue}' value for '{fieldConfig.FieldName}' field.", ex); } } catch (Exception innerEx) { if (ex == innerEx.InnerException) { if (fieldConfig.ErrorMode == ChoErrorMode.IgnoreAndContinue) { continue; } else { if (!RaiseRecordFieldLoadError(rec, pair.Item1, kvp.Key, fieldValue, ex)) { throw new ChoReaderException($"Failed to parse '{fieldValue}' value for '{fieldConfig.FieldName}' field.", ex); } } } else { throw new ChoReaderException("Failed to assign '{0}' fallback value to '{1}' field.".FormatString(fieldValue, fieldConfig.FieldName), innerEx); } } } } return(true); }
internal ChoXmlRecordFieldConfigurationMap(ChoXmlRecordFieldConfiguration config) { _config = config; }
public override void Validate(object state) { base.Validate(state); if (XPath.IsNull()) { throw new ChoRecordConfigurationException("XPath can't be null or whitespace."); } if (XPath.IsNullOrWhiteSpace()) { if (RecordType != null) { NodeName = RecordType.Name; RootName = RecordType.Namespace; } } else { RootName = XPath.SplitNTrim("/").Where(t => !t.IsNullOrWhiteSpace() && t.NTrim() != "." && t.NTrim() != ".." && t.NTrim() != "*").FirstOrDefault(); NodeName = XPath.SplitNTrim("/").Where(t => !t.IsNullOrWhiteSpace() && t.NTrim() != "." && t.NTrim() != ".." && t.NTrim() != "*").Skip(1).FirstOrDefault(); } if (RootName.IsNullOrWhiteSpace()) { ChoXmlDocumentRootAttribute da = TypeDescriptor.GetAttributes(RecordType).OfType <ChoXmlDocumentRootAttribute>().FirstOrDefault(); if (da != null) { NodeName = da.Name; } if (RootName.IsNullOrWhiteSpace()) { RootName = "Root"; } } if (NodeName.IsNullOrWhiteSpace()) { if (!IsDynamicObject) { XmlRootAttribute ra = TypeDescriptor.GetAttributes(RecordType).OfType <XmlRootAttribute>().FirstOrDefault(); if (ra != null) { NodeName = ra.ElementName; } } if (NodeName.IsNullOrWhiteSpace()) { NodeName = "XElement"; } } //Encode Root and node names RootName = System.Net.WebUtility.HtmlEncode(RootName); NodeName = System.Net.WebUtility.HtmlEncode(NodeName); string[] fieldNames = null; XElement xpr = null; if (state is Tuple <long, XElement> ) { xpr = ((Tuple <long, XElement>)state).Item2; } else { fieldNames = state as string[]; } if (AutoDiscoverColumns && XmlRecordFieldConfigurations.Count == 0) { if (RecordType != null && !IsDynamicObject && ChoTypeDescriptor.GetProperties(RecordType).Where(pd => pd.Attributes.OfType <ChoXmlNodeRecordFieldAttribute>().Any()).Any()) { IsComplexXPathUsed = false; long startIndex = 0; long size = 0; string xpath = null; bool useCache = true; ChoXmlNodeRecordFieldAttribute attr = null; foreach (PropertyDescriptor pd in ChoTypeDescriptor.GetProperties(RecordType).Where(pd => pd.Attributes.OfType <ChoXmlNodeRecordFieldAttribute>().Any())) { //if (!pd.PropertyType.IsSimple()) // throw new ChoRecordConfigurationException("Property '{0}' is not a simple type.".FormatString(pd.Name)); attr = ChoTypeDescriptor.GetPropetyAttribute <ChoXmlNodeRecordFieldAttribute>(pd); if (attr.XPath.IsNullOrEmpty()) { xpath = $"//{pd.Name}|//@{pd.Name}"; IsComplexXPathUsed = true; } else { useCache = false; } var obj = new ChoXmlRecordFieldConfiguration(pd.Name, xpath); obj.FieldType = pd.PropertyType; obj.UseCache = useCache; XmlRecordFieldConfigurations.Add(obj); startIndex += size; } //RecordLength = startIndex; } else if (xpr != null) { IsComplexXPathUsed = false; ChoXmlNamespaceManager nsMgr = new ChoXmlNamespaceManager(NamespaceManager); Dictionary <string, ChoXmlRecordFieldConfiguration> dict = new Dictionary <string, ChoXmlRecordFieldConfiguration>(StringComparer.CurrentCultureIgnoreCase); string name = null; foreach (var attr in xpr.Attributes()) { //if (!attr.Name.NamespaceName.IsNullOrWhiteSpace()) continue; name = GetNameWithNamespace(attr.Name); if (!dict.ContainsKey(name)) { dict.Add(name, new ChoXmlRecordFieldConfiguration(name, $"//@{name}")); // DefaultNamespace.IsNullOrWhiteSpace() ? $"//@{name}" : $"//@{DefaultNamespace}" + ":" + $"{name}") { IsXmlAttribute = true }); } else { throw new ChoRecordConfigurationException("Duplicate field(s) [Name(s): {0}] found.".FormatString(name)); } } bool hasElements = false; var z = xpr.Elements().Where(a => !a.HasElements).ToArray(); foreach (var ele in xpr.Elements().Where(a => !a.HasElements)) { name = GetNameWithNamespace(ele.Name); hasElements = true; if (!dict.ContainsKey(name)) { dict.Add(name, new ChoXmlRecordFieldConfiguration(name, $"//{name}")); // DefaultNamespace.IsNullOrWhiteSpace() ? $"//{name}" : $"//{DefaultNamespace}" + ":" + $"{name}")); } else { if (dict[name].IsXmlAttribute) { throw new ChoRecordConfigurationException("Duplicate field(s) [Name(s): {0}] found.".FormatString(name)); } dict[name].IsCollection = true; } } if (!hasElements) { name = xpr.Name.LocalName; dict.Add(name, new ChoXmlRecordFieldConfiguration(name, "text()")); } foreach (ChoXmlRecordFieldConfiguration obj in dict.Values) { XmlRecordFieldConfigurations.Add(obj); } } else if (!fieldNames.IsNullOrEmpty()) { foreach (string fn in fieldNames) { var obj = new ChoXmlRecordFieldConfiguration(fn, xPath: $"//{fn}"); XmlRecordFieldConfigurations.Add(obj); } } } else { IsComplexXPathUsed = false; foreach (var fc in XmlRecordFieldConfigurations) { if (fc.XPath.IsNullOrWhiteSpace()) { fc.XPath = $"//{fc.FieldName}|//@{fc.FieldName}"; } else { if (fc.XPath == fc.FieldName || fc.XPath == $"//{fc.FieldName}" || fc.XPath == $"/{fc.FieldName}" || fc.XPath == $"./{fc.FieldName}" || fc.XPath == $"//@{fc.FieldName}" || fc.XPath == $"/@{fc.FieldName}" || fc.XPath == $"./@{fc.FieldName}" ) { } else { IsComplexXPathUsed = true; fc.UseCache = false; } } } } if (XmlRecordFieldConfigurations.Count <= 0) { throw new ChoRecordConfigurationException("No record fields specified."); } //Validate each record field foreach (var fieldConfig in XmlRecordFieldConfigurations) { fieldConfig.Validate(this); } //Check field position for duplicate string[] dupFields = XmlRecordFieldConfigurations.GroupBy(i => i.Name) .Where(g => g.Count() > 1) .Select(g => g.Key).ToArray(); if (dupFields.Length > 0) { throw new ChoRecordConfigurationException("Duplicate field(s) [Name(s): {0}] found.".FormatString(String.Join(",", dupFields))); } RecordFieldConfigurationsDict = XmlRecordFieldConfigurations.OrderBy(c => c.IsXmlAttribute).Where(i => !i.Name.IsNullOrWhiteSpace()).ToDictionary(i => i.Name); LoadNCacheMembers(XmlRecordFieldConfigurations); }
private ChoXmlReader <T> WithField(string name, string xPath = null, Type fieldType = null, ChoFieldValueTrimOption fieldValueTrimOption = ChoFieldValueTrimOption.Trim, bool isXmlAttribute = false, string fieldName = null, bool isArray = false, Func <object, object> valueConverter = null, Func <object, object> itemConverter = null, Func <object, object> customSerializer = null, object defaultValue = null, object fallbackValue = null, bool encodeValue = false, string fullyQualifiedMemberName = null, string formatText = null, string nullValue = null, Func <XElement, Type> fieldTypeSelector = null) { if (!name.IsNullOrEmpty()) { if (!_clearFields) { ClearFields(); Configuration.MapRecordFields(Configuration.RecordType); } string fnTrim = name.NTrim(); ChoXmlRecordFieldConfiguration fc = null; PropertyDescriptor pd = null; if (Configuration.XmlRecordFieldConfigurations.Any(o => o.Name == fnTrim)) { fc = Configuration.XmlRecordFieldConfigurations.Where(o => o.Name == fnTrim).First(); Configuration.XmlRecordFieldConfigurations.Remove(fc); } else { pd = ChoTypeDescriptor.GetNestedProperty(typeof(T), fullyQualifiedMemberName.IsNullOrWhiteSpace() ? name : fullyQualifiedMemberName); } var nfc = new ChoXmlRecordFieldConfiguration(fnTrim, xPath) { FieldType = fieldType, FieldValueTrimOption = fieldValueTrimOption, IsXmlAttribute = isXmlAttribute, FieldName = fieldName, IsArray = isArray, ValueConverter = valueConverter, ItemConverter = itemConverter, CustomSerializer = customSerializer, DefaultValue = defaultValue, FallbackValue = fallbackValue, EncodeValue = encodeValue, FormatText = formatText, NullValue = nullValue, FieldTypeSelector = fieldTypeSelector, }; if (fullyQualifiedMemberName.IsNullOrWhiteSpace()) { nfc.PropertyDescriptor = fc != null ? fc.PropertyDescriptor : pd; nfc.DeclaringMember = fc != null ? fc.DeclaringMember : fullyQualifiedMemberName; } else { pd = ChoTypeDescriptor.GetNestedProperty(typeof(T), fullyQualifiedMemberName); nfc.PropertyDescriptor = pd; nfc.DeclaringMember = fullyQualifiedMemberName; } if (pd != null) { if (nfc.FieldType == null) { nfc.FieldType = pd.PropertyType; } } Configuration.XmlRecordFieldConfigurations.Add(nfc); } return(this); }
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); }
private bool ToText(long index, object rec, out string recText) { recText = null; 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; msg.AppendFormat("{1}<{0}", Configuration.NodeName, Configuration.Indent); foreach (KeyValuePair <string, ChoXmlRecordFieldConfiguration> kvp in Configuration.RecordFieldConfigurationsDict) { 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); } rec.GetNConvertMemberValue(kvp.Key, kvp.Value, Configuration.Culture, ref fieldValue); 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) { fieldText = String.Empty; } else { fieldText = fieldValue.ToString(); } 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("{2}{2}<{0}>{1}</{0}>{3}".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.Indent, Configuration.EOLDelimiter)); } } if (!isElementClosed) { msg.AppendFormat(">{0}", Configuration.EOLDelimiter); isElementClosed = true; } msg.AppendFormat("{1}</{0}>", Configuration.NodeName, Configuration.Indent); recText = msg.ToString(); return(true); }