/// <summary> /// Parses a PatchFamily element. /// </summary> /// <param name="node">The element to parse.</param> /// <param name="parentType"></param> /// <param name="parentId"></param> private void ParsePatchFamilyElement(XElement node, ComplexReferenceParentType parentType, string parentId) { var sourceLineNumbers = Preprocessor.GetSourceLineNumbers(node); Identifier id = null; string productCode = null; string version = null; var attributes = 0; foreach (var attrib in node.Attributes()) { if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || CompilerCore.WixNamespace == attrib.Name.Namespace) { switch (attrib.Name.LocalName) { case "Id": id = this.Core.GetAttributeIdentifier(sourceLineNumbers, attrib); break; case "ProductCode": productCode = this.Core.GetAttributeGuidValue(sourceLineNumbers, attrib, false); break; case "Version": version = this.Core.GetAttributeVersionValue(sourceLineNumbers, attrib); break; case "Supersede": if (YesNoType.Yes == this.Core.GetAttributeYesNoValue(sourceLineNumbers, attrib)) { attributes |= 0x1; } break; default: this.Core.UnexpectedAttribute(node, attrib); break; } } else { this.Core.ParseExtensionAttribute(node, attrib); } } if (null == id) { this.Core.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Id")); id = Identifier.Invalid; } if (String.IsNullOrEmpty(version)) { this.Core.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Version")); } else if (!CompilerCore.IsValidProductVersion(version)) { this.Core.Write(ErrorMessages.InvalidProductVersion(sourceLineNumbers, version)); } // find unexpected child elements foreach (var child in node.Elements()) { if (CompilerCore.WixNamespace == child.Name.Namespace) { switch (child.Name.LocalName) { case "All": this.ParseAllElement(child); break; case "BinaryRef": this.ParsePatchChildRefElement(child, "Binary"); break; case "ComponentRef": this.ParsePatchChildRefElement(child, "Component"); break; case "CustomActionRef": this.ParsePatchChildRefElement(child, "CustomAction"); break; case "DirectoryRef": this.ParsePatchChildRefElement(child, "Directory"); break; case "DigitalCertificateRef": this.ParsePatchChildRefElement(child, "MsiDigitalCertificate"); break; case "FeatureRef": this.ParsePatchChildRefElement(child, "Feature"); break; case "IconRef": this.ParsePatchChildRefElement(child, "Icon"); break; case "PropertyRef": this.ParsePatchChildRefElement(child, "Property"); break; case "SoftwareTagRef": this.ParseTagRefElement(child); break; case "UIRef": this.ParsePatchChildRefElement(child, "WixUI"); break; default: this.Core.UnexpectedElement(node, child); break; } } else { this.Core.ParseExtensionElement(node, child); } } if (!this.Core.EncounteredError) { this.Core.AddSymbol(new MsiPatchSequenceSymbol(sourceLineNumbers) { PatchFamily = id.Id, ProductCode = productCode, Sequence = version, Attributes = attributes }); if (ComplexReferenceParentType.Unknown != parentType) { this.Core.CreateComplexReference(sourceLineNumbers, parentType, parentId, null, ComplexReferenceChildType.PatchFamily, id.Id, ComplexReferenceParentType.Patch == parentType); } } }