/// <summary> /// Called as part for the deserialization chain. Returns false if it cannot serialize the XML element. /// </summary> public override bool Deserialize(XElement node, ITypeData t, Action <object> setter) { if ((node.Name.LocalName == "Package" && t.IsA(typeof(PackageDef))) || (node.Name.LocalName == nameof(PackageIdentifier) && t.IsA(typeof(PackageIdentifier)))) { var pkg = new PackageDef(); foreach (XAttribute attr in node.Attributes()) { switch (attr.Name.LocalName) { case "Version": pkg.RawVersion = attr.Value; if (SemanticVersion.TryParse(attr.Value, out var semver)) { pkg.Version = semver; } break; case "Date": if (DateTime.TryParse(attr.Value, out DateTime date)) { pkg.Date = date; } else { pkg.Date = DateTime.MinValue; } break; case "Architecture": pkg.Architecture = (CpuArchitecture)Enum.Parse(typeof(CpuArchitecture), attr.Value); break; default: var prop = pkg.GetType().GetProperty(attr.Name.LocalName); if (prop != null) { prop.SetValue(pkg, attr.Value); } break; } } foreach (var elm in node.Elements()) { switch (elm.Name.LocalName) { case "Description": pkg.Description = Regex.Match(elm.ToString().Replace("\r", ""), "^<Description.*?>((?:.|\\n)+)</Description>", RegexOptions.Multiline).Groups[1].Value.Trim(); break; case "PackageRepositoryUrl": #pragma warning disable 618 pkg.Location = elm.Value; #pragma warning restore 618 break; default: var prop = pkg.GetType().GetProperty(elm.Name.LocalName); if (prop != null) { Serializer.Deserialize(elm, o => prop.SetValue(pkg, o), prop.PropertyType); } break; } } if (t.IsA(typeof(PackageIdentifier))) { setter.Invoke(new PackageIdentifier(pkg)); } else { setter.Invoke(pkg); } // If the Version XML attribute is missing, default to same behavior as if Version="" was specified. We depend on packages having a version. if (pkg.Version is null && string.IsNullOrEmpty(pkg.RawVersion)) { pkg.RawVersion = ""; if (SemanticVersion.TryParse("0.0.0", out var semver)) { pkg.Version = semver; } } return(true); } return(false); }