/// <summary> /// Pasre a ProjectItemDefinitionElement /// </summary> private ProjectItemDefinitionElement ParseProjectItemDefinitionXml(XmlElementWithLocation element, ProjectItemDefinitionGroupElement parent) { // Orcas inadvertently did not check for reserved item types (like "Choose") in item definitions, // as we do for item types in item groups. So we do not have a check here. // Although we could perhaps add one, as such item definitions couldn't be used // since no items can have the reserved itemType. ProjectItemDefinitionElement itemDefinition = new ProjectItemDefinitionElement(element, parent, _project); foreach (XmlAttributeWithLocation attribute in element.Attributes) { CheckMetadataAsAttributeName(attribute.Name, out bool isKnownAttribute, out bool isValidMetadataNameInAttribute); if (!isKnownAttribute && !isValidMetadataNameInAttribute) { ProjectXmlUtilities.ThrowProjectInvalidAttribute(attribute); } else if (isValidMetadataNameInAttribute) { ProjectMetadataElement metadatum = _project.CreateMetadataElement(attribute.Name, attribute.Value); metadatum.ExpressedAsAttribute = true; metadatum.Parent = itemDefinition; itemDefinition.AppendParentedChildNoChecks(metadatum); } else if (!ValidAttributesOnlyConditionAndLabel.Contains(attribute.Name)) { ProjectXmlUtilities.ThrowProjectInvalidAttribute(attribute); } } foreach (XmlElementWithLocation childElement in ProjectXmlUtilities.GetVerifyThrowProjectChildElements(element)) { ProjectMetadataElement metadatum = ParseProjectMetadataElement(childElement, itemDefinition); itemDefinition.AppendParentedChildNoChecks(metadatum); } return(itemDefinition); }
/// <summary> /// Parse a ProjectItemElement /// </summary> private ProjectItemElement ParseProjectItemElement(XmlElementWithLocation element, ProjectItemGroupElement parent) { bool belowTarget = parent.Parent is ProjectTargetElement; string itemType = element.Name; string include = element.GetAttribute(XMakeAttributes.include); string exclude = element.GetAttribute(XMakeAttributes.exclude); string remove = element.GetAttribute(XMakeAttributes.remove); string update = element.GetAttribute(XMakeAttributes.update); var exclusiveItemOperation = ""; int exclusiveAttributeCount = 0; if (element.HasAttribute(XMakeAttributes.include)) { exclusiveAttributeCount++; exclusiveItemOperation = XMakeAttributes.include; } if (element.HasAttribute(XMakeAttributes.remove)) { exclusiveAttributeCount++; exclusiveItemOperation = XMakeAttributes.remove; } if (element.HasAttribute(XMakeAttributes.update)) { exclusiveAttributeCount++; exclusiveItemOperation = XMakeAttributes.update; } // At most one of the include, remove, or update attributes may be specified if (exclusiveAttributeCount > 1) { XmlAttributeWithLocation errorAttribute = remove.Length > 0 ? (XmlAttributeWithLocation)element.Attributes[XMakeAttributes.remove] : (XmlAttributeWithLocation)element.Attributes[XMakeAttributes.update]; ProjectErrorUtilities.ThrowInvalidProject(errorAttribute.Location, "InvalidAttributeExclusive"); } // Include, remove, or update must be present unless inside a target ProjectErrorUtilities.VerifyThrowInvalidProject(exclusiveAttributeCount == 1 || belowTarget, element.Location, "IncludeRemoveOrUpdate", exclusiveItemOperation, itemType); // Exclude must be missing, unless Include exists ProjectXmlUtilities.VerifyThrowProjectInvalidAttribute(exclude.Length == 0 || include.Length > 0, (XmlAttributeWithLocation)element.Attributes[XMakeAttributes.exclude]); // If we have an Include attribute at all, it must have non-zero length ProjectErrorUtilities.VerifyThrowInvalidProject(include.Length > 0 || element.Attributes[XMakeAttributes.include] == null, element.Location, "MissingRequiredAttribute", XMakeAttributes.include, itemType); // If we have a Remove attribute at all, it must have non-zero length ProjectErrorUtilities.VerifyThrowInvalidProject(remove.Length > 0 || element.Attributes[XMakeAttributes.remove] == null, element.Location, "MissingRequiredAttribute", XMakeAttributes.remove, itemType); // If we have an Update attribute at all, it must have non-zero length ProjectErrorUtilities.VerifyThrowInvalidProject(update.Length > 0 || element.Attributes[XMakeAttributes.update] == null, element.Location, "MissingRequiredAttribute", XMakeAttributes.update, itemType); XmlUtilities.VerifyThrowProjectValidElementName(element); ProjectErrorUtilities.VerifyThrowInvalidProject(!XMakeElements.ReservedItemNames.Contains(itemType), element.Location, "CannotModifyReservedItem", itemType); ProjectItemElement item = new ProjectItemElement(element, parent, _project); foreach (XmlAttributeWithLocation attribute in element.Attributes) { bool isKnownAttribute; bool isValidMetadataNameInAttribute; CheckMetadataAsAttributeName(attribute.Name, out isKnownAttribute, out isValidMetadataNameInAttribute); if (!isKnownAttribute && !isValidMetadataNameInAttribute) { ProjectXmlUtilities.ThrowProjectInvalidAttribute(attribute); } else if (isValidMetadataNameInAttribute) { ProjectMetadataElement metadatum = _project.CreateMetadataElement(attribute.Name, attribute.Value); metadatum.ExpressedAsAttribute = true; metadatum.Parent = item; item.AppendParentedChildNoChecks(metadatum); } } foreach (XmlElementWithLocation childElement in ProjectXmlUtilities.GetVerifyThrowProjectChildElements(element)) { ProjectMetadataElement metadatum = ParseProjectMetadataElement(childElement, item); item.AppendParentedChildNoChecks(metadatum); } return(item); }