public void Attributes() { using (var context = new UnitTestContext(this)) { string eol = StringUtil.Eol; string xmlText = "<?xml version=\"1.0\" encoding=\"utf-8\"?>" + eol + "<firstElement attributeOfFirstElement1=\"AttributeValue1\" attributeOfFirstElement2=\"AttributeValue2\">" + eol + " <secondElement>" + eol + " <valueElement1>TestValue1</valueElement1>" + eol + " <valueElement2 attributeOfValueElement=\"AttributeValue\">TestValue2</valueElement2>" + eol + " </secondElement>" + eol + "</firstElement>" + eol; // Create XML reader ITreeReader reader = new XmlTreeReader(xmlText); // Read root element with two attributes ITreeReader firstElement = reader.ReadElement("firstElement"); context.Log.Verify($"attributeOfFirstElement1={firstElement.ReadAttribute("attributeOfFirstElement1")}"); context.Log.Verify($"attributeOfFirstElement2={firstElement.ReadAttribute("attributeOfFirstElement2")}"); // Read embedded element ITreeReader secondElement = firstElement.ReadElement("secondElement"); // Read value element using a single method call string valueElement1 = secondElement.ReadValueElement("valueElement1"); context.Log.Verify($"valueElement1={valueElement1}"); // Add value element with two attributes by creating element explicitly ITreeReader valueElementNode2 = secondElement.ReadElement("valueElement2"); string valueElement2 = valueElementNode2.ReadValue(); context.Log.Verify($"attributeOfValueElement={valueElementNode2.ReadAttribute("attributeOfValueElement")}"); context.Log.Verify($"valueElement2={valueElement2}"); } }
/// <summary>Deserialize from data in ITreeReader.</summary> public void DeserializeFrom(ITreeReader reader) { // Do nothing if the selected XML node is empty if (reader == null) { return; } // Iterate over the list of elements var elementInfoList = DataTypeInfo.GetOrCreate(this).DataElements; foreach (var elementInfo in elementInfoList) { // Get element name and type string elementName = elementInfo.Name; Type elementType = elementInfo.PropertyType; // Get inner XML node, continue with next element if null ITreeReader innerXmlNode = reader.ReadElement(elementName); if (innerXmlNode == null) { continue; } // First check for each of the supported value types if (elementType == typeof(string)) { string token = innerXmlNode.ReadValue(); elementInfo.SetValue(this, token); } else if (elementType == typeof(double) || elementType == typeof(double?)) { string token = innerXmlNode.ReadValue(); var value = double.Parse(token); elementInfo.SetValue(this, value); } else if (elementType == typeof(bool) || elementType == typeof(bool?)) { string token = innerXmlNode.ReadValue(); var value = bool.Parse(token); elementInfo.SetValue(this, value); } else if (elementType == typeof(int) || elementType == typeof(int?)) { string token = innerXmlNode.ReadValue(); var value = int.Parse(token); elementInfo.SetValue(this, value); } else if (elementType == typeof(long) || elementType == typeof(long?)) { string token = innerXmlNode.ReadValue(); var value = long.Parse(token); elementInfo.SetValue(this, value); } else if (elementType == typeof(LocalDate) || elementType == typeof(LocalDate?)) { string token = innerXmlNode.ReadValue(); var value = LocalDateUtil.Parse(token); elementInfo.SetValue(this, value); } else if (elementType == typeof(LocalTime) || elementType == typeof(LocalTime?)) { string token = innerXmlNode.ReadValue(); var value = LocalTimeUtil.Parse(token); elementInfo.SetValue(this, value); } else if (elementType == typeof(LocalMinute) || elementType == typeof(LocalMinute?)) { string token = innerXmlNode.ReadValue(); var value = LocalMinuteUtil.Parse(token); elementInfo.SetValue(this, value); } else if (elementType == typeof(LocalDateTime) || elementType == typeof(LocalDateTime?)) { string token = innerXmlNode.ReadValue(); var value = LocalDateTimeUtil.Parse(token); elementInfo.SetValue(this, value); } else if (elementType == typeof(Instant) || elementType == typeof(Instant?)) { string token = innerXmlNode.ReadValue(); var value = InstantUtil.Parse(token); elementInfo.SetValue(this, value); } else if (elementType.IsSubclassOf(typeof(Enum))) { string token = innerXmlNode.ReadValue(); var value = Enum.Parse(elementType, token); elementInfo.SetValue(this, value); } else { // If none of the supported atomic types match, use the activator // to create and empty instance of a complex type and populate it var element = Activator.CreateInstance(elementType); switch (element) { case IList listElement: listElement.DeserializeFrom(elementName, reader); break; case Data dataElement: var keyElement = dataElement as Key; if (keyElement != null) { // Deserialize key from value node containing semicolon delimited string string token = innerXmlNode.ReadValue(); // Parse semicolon delimited string to populate key elements keyElement.PopulateFrom(token); } else { // Deserialize embedded data object from the contents of inner XML node dataElement.DeserializeFrom(innerXmlNode); } break; case TemporalId idElement: // Do not serialize break; default: // Error message if the type does not match any of the value or reference types throw new Exception($"Serialization is not supported for type {elementType}."); } // Assign the populated key to the property elementInfo.SetValue(this, element); } } }