private static Type GetWrittenType(XmlReader reader, string elementName, Type objType) { var writtenTypeName = reader.GetAttribute("type"); if (writtenTypeName == null) return GetSerializedType(objType); Type writtenType; if (!g_typeNameToType.TryGetValue(writtenTypeName, out writtenType)) { writtenType = Type.GetType(writtenTypeName) ?? AppDomain.CurrentDomain.GetAssemblies() .Select(assembly => assembly.GetType(writtenTypeName)) .Where(type => type != null) .FirstOrDefault(); if (writtenType == null) throw new XmlException("XML suggests unknown type " + writtenTypeName, null, reader.LineNumber(), reader.LinePosition()); g_typeNameToType.Add(writtenTypeName, writtenType); } if (!IsAssignableFrom(objType, writtenType)) throw new XmlException("XML suggests type " + writtenTypeName + " that is not assignable to expected type " + objType.Name, null, reader.LineNumber(), reader.LinePosition()); return writtenType; }
internal SortedDictionary <string, string> GetItems(NodeStructure root, XmlReader reader) { var namespaces = new SortedDictionary <string, string>(); NodeStructure buffer = root; bool closePrev = false; while (reader.Read()) { int ln = reader.LineNumber(); int lp = reader.LinePosition(); if (closePrev) { buffer.LineNumberEnd = ln; buffer.PositionEnd = lp - 1; buffer = buffer.Parent; closePrev = false; } if (reader.NodeType == XmlNodeType.Element) { //sb.Append($"{ln} {lp} {reader.Depth} {reader.LocalName}\r\n"); buffer = new NodeStructure(reader.LocalName, reader.Depth, buffer) { Namespace = reader.NamespaceURI, LineNumberStart = ln, PositionStart = lp - 2, Prefix = reader.Prefix }; buffer.Parent.Items.Add(buffer); if (reader.AttributeCount > 0) { for (int i = 0; i < reader.AttributeCount; i++) { reader.MoveToAttribute(i); string nameAttribute = reader.Name; if (nameAttribute != "xmlns" && !nameAttribute.StartsWith("xmlns:")) { buffer.Attributes.Add(nameAttribute, reader.Value); } } reader.MoveToElement(); } if (!string.IsNullOrEmpty(buffer.Namespace) && !namespaces.ContainsKey(buffer.Prefix)) { namespaces.Add(buffer.Prefix, buffer.Namespace); } closePrev = reader.IsEmptyElement; } else if (reader.NodeType == XmlNodeType.EndElement) { if (buffer != null) { buffer.LineNumberEnd = ln; buffer.PositionEnd = lp + buffer.NodeName.Length + (!string.IsNullOrEmpty(buffer.Prefix) ? buffer.Prefix.Length + 1 : 0); buffer = buffer.Parent; } } } return(namespaces); }
/// <summary> /// Reads in fields and properties of an object from an XML reader. /// </summary> /// <remarks> /// <para> /// You can limit the deserialisation to members that have the specified limitation attribute. /// This limitation is applied only to instances of classes that have /// LimitedSerializationAttribute. ///</para> ///<para> /// The XML reader is assumed to be positioned on the first child element of /// the root element of the serialised 'obj' to be read. At successful return, /// the XML reader will be positioned at the end element of the serialised 'obj'. /// A log message is produced if an unknown serialised member is encountered. /// It is guaranteed that all fields and properties (marked with <paramref name="limitationAttribute"/> /// get a value exactly once, lest an exception is thrown. /// </para> /// </remarks> /// <param name="reader">Where to read the serialised values.</param> /// <param name="obj">The object whose members to deserialise.</param> /// <param name="limitationAttribute">Limit the deserialisation to members with this attribute, /// or deserialise all members if limitationAttribute is a null reference.</param> /// <seealso cref="AW2.Helpers.LimitedSerializationAttribute"/> private static void DeserializeFieldsAndPropertiesXml(XmlReader reader, object obj, Type limitationAttribute, bool tolerant) { try { var type = obj.GetType(); var finder = new FieldAndPropertyFinder(obj.GetType(), limitationAttribute, tolerant); // NOTE: There is no guarantee about the order of the members. while (reader.IsStartElement()) { var member = finder.Find(reader.Name); if (member == null) { reader.Skip(); continue; } var memberLimitationAttribute = GetLimitationAttribute(member, limitationAttribute); var value = DeserializeXml(reader, reader.Name, member.ValueType, memberLimitationAttribute, tolerant); member.SetValue(obj, value); } finder.CheckForMissing(); } catch (MemberSerializationException e) { e.LineNumber = reader.LineNumber(); throw; } }