void ProcessAttributesToMember(XamlSchemaContext sctx, StartTagInfo sti, XamlType xt) { foreach (var p in sti.Attributes) { int nsidx = p.Key.IndexOf(':'); string prefix = nsidx > 0 ? p.Key.Substring(0, nsidx) : String.Empty; string aname = nsidx > 0 ? p.Key.Substring(nsidx + 1) : p.Key; int propidx = aname.IndexOf('.'); if (propidx > 0) { string apns = r.LookupNamespace(prefix); var apname = aname.Substring(0, propidx); var axtn = new XamlTypeName(apns, apname, null); if (xt.UnderlyingType == null) { var am = XamlMember.FromUnknown(aname.Substring(propidx + 1), apns, new XamlType(apns, apname, new List <XamlType>(), sctx)); sti.Members.Add(new Pair(am, p.Value)); } else { var at = sctx.GetXamlType(axtn); var am = at.GetAttachableMember(aname.Substring(propidx + 1)); if (am != null) { sti.Members.Add(new Pair(am, p.Value)); } else { sti.Members.Add(new Pair(XamlMember.FromUnknown(aname, apns, new XamlType(apns, apname, new List <XamlType>(), sctx)), p.Value)); } } } else { var xm = xt.GetMember(aname); if (xm != null) { sti.Members.Add(new Pair(xm, p.Value)); } else { sti.Members.Add(new Pair(XamlMember.FromUnknown(p.Key, r.NamespaceURI, xt), p.Value)); } } } }
// member element, implicit member, children via content property, or value IEnumerable <XamlXmlNodeInfo> ReadMemberElement(XamlType parentType, XamlType xt) { if (IsIgnored(r.Prefix)) { r.Skip(); yield break; } XamlMember xm = null; var name = r.LocalName; int idx = name.IndexOf('.'); // FIXME: it skips strict type name check, as it could result in MarkupExtension mismatch (could be still checked, though) if (idx >= 0 /* && name.Substring (0, idx) == xt.Name*/) { name = name.Substring(idx + 1); xm = xt.GetMember(name); } else { xm = (XamlMember)FindStandardDirective(name, AllowedMemberLocations.MemberElement) ?? // not a standard directive? then try attachable xt.GetAttachableMember(name) ?? // still not? then try ordinal member xt.GetMember(name); if (xm == null) { // still not? could it be omitted as content property or items ? if ((xm = GetExtraMember(xt)) != null) { // Note that this does not involve r.Read() foreach (var ni in ReadMember(xt, xm)) { yield return(ni); } yield break; } } } if (xm == null) { // Current element could be for another member in the parent type (if exists) if (parentType != null && parentType.GetMember(name) != null) { // stop the iteration and signal the caller to not read current element as an object. (It resolves conflicts between "start object for current collection's item" and "start member for the next member in the parent object". yield return(Node(XamlNodeType.None, null)); yield break; } // ok, then create unknown member. if (idx >= 0) { var declaringType = new XamlType(r.NamespaceURI, r.LocalName.Substring(0, idx), new List <XamlType>(), new XamlSchemaContext()); xm = XamlMember.FromUnknown(name, r.NamespaceURI, declaringType); // FIXME: not sure if isAttachable is always false. } else { xm = XamlMember.FromUnknown(name, r.NamespaceURI, xt); // FIXME: not sure if isAttachable is always false. } } if (!r.IsEmptyElement) { if (idx == -1 && !xm.IsDirective && xm.DeclaringType.UnderlyingType == null) { foreach (var ni in ReadCollectionItems(xt, xm)) { yield return(ni); } } else { r.Read(); foreach (var ni in ReadMember(xt, xm)) { yield return(ni); } if (!r.IsEmptyElement) { r.MoveToContent(); r.ReadEndElement(); } } } else { if (r.Name.Contains(".") && r.IsEmptyElement && !r.HasAttributes) { // This case is present to handle self closing attached property nodes. yield return(Node(XamlNodeType.StartMember, xm)); yield return(Node(XamlNodeType.EndMember, xm)); r.Read(); yield break; } else { foreach (var ni in ReadCollectionItems(xt, xm)) { yield return(ni); } } } }