Ejemplo n.º 1
0
        /// <summary>
        /// Parse a localization string.
        /// </summary>
        /// <param name="node">Element to parse.</param>
        private void ParseString(XmlNode node)
        {
            string id          = null;
            bool   overridable = false;
            SourceLineNumberCollection sourceLineNumbers = Preprocessor.GetSourceLineNumbers(node);

            foreach (XmlAttribute attrib in node.Attributes)
            {
                if (0 == attrib.NamespaceURI.Length || attrib.NamespaceURI == Localization.XmlNamespaceUri)
                {
                    switch (attrib.LocalName)
                    {
                    case "Id":
                        id = Common.GetAttributeIdentifierValue(sourceLineNumbers, attrib, null);
                        break;

                    case "Overridable":
                        overridable = Common.IsYes(sourceLineNumbers, "String", attrib.Name, attrib.Value);
                        break;

                    case "Localizable":
                        ;     // do nothing
                        break;

                    default:
                        throw new WixException(WixErrors.UnexpectedAttribute(sourceLineNumbers, attrib.OwnerElement.Name, attrib.Name));
                    }
                }
                else
                {
                    throw new WixException(WixErrors.UnsupportedExtensionAttribute(sourceLineNumbers, attrib.OwnerElement.Name, attrib.Name));
                }
            }

            string value = node.InnerText;

            if (null == id)
            {
                throw new WixException(WixErrors.ExpectedAttribute(sourceLineNumbers, "String", "Id"));
            }

            WixVariableRow wixVariableRow = new WixVariableRow(sourceLineNumbers, this.tableDefinitions["WixVariable"]);

            wixVariableRow.Id          = id;
            wixVariableRow.Overridable = overridable;
            wixVariableRow.Value       = value;

            WixVariableRow existingWixVariableRow = (WixVariableRow)this.variables[id];

            if (null == existingWixVariableRow || (existingWixVariableRow.Overridable && !overridable))
            {
                this.variables.Add(id, wixVariableRow);
            }
            else if (!overridable)
            {
                throw new WixException(WixErrors.DuplicateLocalizationIdentifier(sourceLineNumbers, id));
            }
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Parses a column definition in a table definition.
        /// </summary>
        /// <param name="reader">Reader to get data from.</param>
        /// <returns>The ColumnDefintion represented by the Xml.</returns>
        internal static ColumnDefinition Parse(XmlReader reader)
        {
            Debug.Assert("columnDefinition" == reader.LocalName);

            bool                 added               = false;
            ColumnCategory       category            = ColumnCategory.Unknown;
            string               description         = null;
            bool                 empty               = reader.IsEmptyElement;
            bool                 escapeIdtCharacters = false;
            int                  keyColumn           = -1;
            bool                 keyColumnSet        = false;
            string               keyTable            = null;
            int                  length              = -1;
            bool                 localizable         = false;
            int                  maxValue            = 0;
            bool                 maxValueSet         = false;
            int                  minValue            = 0;
            bool                 minValueSet         = false;
            ColumnModularizeType modularize          = ColumnModularizeType.None;
            string               name          = null;
            bool                 nullable      = false;
            string               possibilities = null;
            bool                 primaryKey    = false;
            ColumnType           type          = ColumnType.Unknown;
            bool                 useCData      = false;

            // parse the attributes
            while (reader.MoveToNextAttribute())
            {
                switch (reader.LocalName)
                {
                case "added":
                    added = Common.IsYes(SourceLineNumberCollection.FromUri(reader.BaseURI), "columnDefinition", reader.Name, reader.Value);
                    break;

                case "category":
                    switch (reader.Value)
                    {
                    case "anyPath":
                        category = ColumnCategory.AnyPath;
                        break;

                    case "binary":
                        category = ColumnCategory.Binary;
                        break;

                    case "cabinet":
                        category = ColumnCategory.Cabinet;
                        break;

                    case "condition":
                        category = ColumnCategory.Condition;
                        break;

                    case "customSource":
                        category = ColumnCategory.CustomSource;
                        break;

                    case "defaultDir":
                        category = ColumnCategory.DefaultDir;
                        break;

                    case "doubleInteger":
                        category = ColumnCategory.DoubleInteger;
                        break;

                    case "filename":
                        category = ColumnCategory.Filename;
                        break;

                    case "formatted":
                        category = ColumnCategory.Formatted;
                        break;

                    case "formattedSddl":
                        category = ColumnCategory.FormattedSDDLText;
                        break;

                    case "guid":
                        category = ColumnCategory.Guid;
                        break;

                    case "identifier":
                        category = ColumnCategory.Identifier;
                        break;

                    case "integer":
                        category = ColumnCategory.Integer;
                        break;

                    case "language":
                        category = ColumnCategory.Language;
                        break;

                    case "lowerCase":
                        category = ColumnCategory.LowerCase;
                        break;

                    case "path":
                        category = ColumnCategory.Path;
                        break;

                    case "paths":
                        category = ColumnCategory.Paths;
                        break;

                    case "property":
                        category = ColumnCategory.Property;
                        break;

                    case "regPath":
                        category = ColumnCategory.RegPath;
                        break;

                    case "shortcut":
                        category = ColumnCategory.Shortcut;
                        break;

                    case "template":
                        category = ColumnCategory.Template;
                        break;

                    case "text":
                        category = ColumnCategory.Text;
                        break;

                    case "timeDate":
                        category = ColumnCategory.TimeDate;
                        break;

                    case "upperCase":
                        category = ColumnCategory.UpperCase;
                        break;

                    case "version":
                        category = ColumnCategory.Version;
                        break;

                    case "wildCardFilename":
                        category = ColumnCategory.WildCardFilename;
                        break;

                    default:
                        throw new WixException(WixErrors.IllegalAttributeValue(SourceLineNumberCollection.FromUri(reader.BaseURI), "columnDefinition", reader.Name, reader.Value, "anyPath", "binary", "cabinet", "condition", "customSource", "defaultDir", "doubleInteger", "filename", "formatted", "formattedSddl", "guid", "identifier", "integer", "language", "lowerCase", "path", "paths", "property", "regPath", "shortcut", "template", "text", "timeDate", "upperCase", "version", "wildCardFilename"));
                    }
                    break;

                case "description":
                    description = reader.Value;
                    break;

                case "escapeIdtCharacters":
                    escapeIdtCharacters = Common.IsYes(SourceLineNumberCollection.FromUri(reader.BaseURI), "columnDefinition", reader.Name, reader.Value);
                    break;

                case "keyColumn":
                    keyColumnSet = true;
                    keyColumn    = Convert.ToInt32(reader.Value, 10);
                    break;

                case "keyTable":
                    keyTable = reader.Value;
                    break;

                case "length":
                    length = Convert.ToInt32(reader.Value, 10);
                    break;

                case "localizable":
                    localizable = Common.IsYes(SourceLineNumberCollection.FromUri(reader.BaseURI), "columnDefinition", reader.Name, reader.Value);
                    break;

                case "maxValue":
                    maxValueSet = true;
                    maxValue    = Convert.ToInt32(reader.Value, 10);
                    break;

                case "minValue":
                    minValueSet = true;
                    minValue    = Convert.ToInt32(reader.Value, 10);
                    break;

                case "modularize":
                    switch (reader.Value)
                    {
                    case "column":
                        modularize = ColumnModularizeType.Column;
                        break;

                    case "companionFile":
                        modularize = ColumnModularizeType.CompanionFile;
                        break;

                    case "condition":
                        modularize = ColumnModularizeType.Condition;
                        break;

                    case "controlEventArgument":
                        modularize = ColumnModularizeType.ControlEventArgument;
                        break;

                    case "controlText":
                        modularize = ColumnModularizeType.ControlText;
                        break;

                    case "icon":
                        modularize = ColumnModularizeType.Icon;
                        break;

                    case "none":
                        modularize = ColumnModularizeType.None;
                        break;

                    case "property":
                        modularize = ColumnModularizeType.Property;
                        break;

                    case "semicolonDelimited":
                        modularize = ColumnModularizeType.SemicolonDelimited;
                        break;

                    default:
                        throw new WixException(WixErrors.IllegalAttributeValue(SourceLineNumberCollection.FromUri(reader.BaseURI), "columnDefinition", reader.Name, reader.Value, "column", "companionFile", "condition", "controlEventArgument", "controlText", "icon", "property", "semicolonDelimited"));
                    }
                    break;

                case "name":
                    switch (reader.Value)
                    {
                    case "CREATE":
                    case "DELETE":
                    case "DROP":
                    case "INSERT":
                        throw new WixException(WixErrors.IllegalColumnName(SourceLineNumberCollection.FromUri(reader.BaseURI), "columnDefinition", reader.Name, reader.Value));

                    default:
                        name = reader.Value;
                        break;
                    }
                    break;

                case "nullable":
                    nullable = Common.IsYes(SourceLineNumberCollection.FromUri(reader.BaseURI), "columnDefinition", reader.Name, reader.Value);
                    break;

                case "primaryKey":
                    primaryKey = Common.IsYes(SourceLineNumberCollection.FromUri(reader.BaseURI), "columnDefinition", reader.Name, reader.Value);
                    break;

                case "set":
                    possibilities = reader.Value;
                    break;

                case "type":
                    switch (reader.Value)
                    {
                    case "localized":
                        type = ColumnType.Localized;
                        break;

                    case "number":
                        type = ColumnType.Number;
                        break;

                    case "object":
                        type = ColumnType.Object;
                        break;

                    case "string":
                        type = ColumnType.String;
                        break;

                    case "preserved":
                        type = ColumnType.Preserved;
                        break;

                    default:
                        throw new WixException(WixErrors.IllegalAttributeValue(SourceLineNumberCollection.FromUri(reader.BaseURI), "columnDefinition", reader.Name, reader.Value, "localized", "number", "object", "string"));
                    }
                    break;

                case "useCData":
                    useCData = Common.IsYes(SourceLineNumberCollection.FromUri(reader.BaseURI), "columnDefinition", reader.Name, reader.Value);
                    break;

                default:
                    if (!reader.NamespaceURI.StartsWith("http://www.w3.org/", StringComparison.Ordinal))
                    {
                        throw new WixException(WixErrors.UnexpectedAttribute(SourceLineNumberCollection.FromUri(reader.BaseURI), "columnDefinition", reader.Name));
                    }
                    break;
                }
            }

            // parse the child elements (there should be none)
            if (!empty)
            {
                bool done = false;

                while (!done && reader.Read())
                {
                    switch (reader.NodeType)
                    {
                    case XmlNodeType.Element:
                        throw new WixException(WixErrors.UnexpectedElement(SourceLineNumberCollection.FromUri(reader.BaseURI), "columnDefinition", reader.Name));

                    case XmlNodeType.EndElement:
                        done = true;
                        break;
                    }
                }

                if (!done)
                {
                    throw new WixException(WixErrors.ExpectedEndElement(SourceLineNumberCollection.FromUri(reader.BaseURI), "columnDefinition"));
                }
            }

            ColumnDefinition columnDefinition = new ColumnDefinition(name, type, length, primaryKey, nullable, modularize, localizable, minValueSet, minValue, maxValueSet, maxValue, keyTable, keyColumnSet, keyColumn, category, possibilities, description, escapeIdtCharacters, useCData);

            columnDefinition.Added = added;

            return(columnDefinition);
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Parse a complex reference from the xml.
        /// </summary>
        /// <param name="intermediate">Intermediate to populate with persisted data.</param>
        /// <param name="reader">XmlReader where the intermediate is persisted.</param>
        /// <param name="section">Section to populate with persisted data.</param>
        private static void ParseComplexReference(Intermediate intermediate, XmlReader reader, Section section)
        {
            bool empty = reader.IsEmptyElement;
            ComplexReferenceParentType parentType = ComplexReferenceParentType.Unknown;
            string parentId       = null;
            string parentLanguage = null;
            ComplexReferenceChildType childType = ComplexReferenceChildType.Unknown;
            string childId = null;
            bool   primary = false;

            while (reader.MoveToNextAttribute())
            {
                switch (reader.LocalName)
                {
                case "parent":
                    parentId = reader.Value;
                    break;

                case "parentLanguage":
                    parentLanguage = reader.Value;
                    break;

                case "parentType":
                    switch (reader.Value)
                    {
                    case "componentGroup":
                        parentType = ComplexReferenceParentType.ComponentGroup;
                        break;

                    case "feature":
                        parentType = ComplexReferenceParentType.Feature;
                        break;

                    case "module":
                        parentType = ComplexReferenceParentType.Module;
                        break;
                    }
                    break;

                case "child":
                    childId = reader.Value;
                    break;

                case "childType":
                    switch (reader.Value)
                    {
                    case "component":
                        childType = ComplexReferenceChildType.Component;
                        break;

                    case "componentGroup":
                        childType = ComplexReferenceChildType.ComponentGroup;
                        break;

                    case "feature":
                        childType = ComplexReferenceChildType.Feature;
                        break;

                    case "fragment":
                        childType = ComplexReferenceChildType.Fragment;
                        break;

                    case "module":
                        childType = ComplexReferenceChildType.Module;
                        break;
                    }
                    break;

                case "primary":
                    primary = Common.IsYes(reader.Value, SourceLineNumberCollection.FromFileName(intermediate.Path), "complexReference", "primary", parentId);
                    break;
                }
            }
            if (ComplexReferenceParentType.Unknown == parentType)
            {
                throw new WixInvalidIntermediateException(SourceLineNumberCollection.FromFileName(intermediate.Path), "Unknown ComplexReferenceParentType type");
            }
            if (null == parentId)
            {
                throw new WixInvalidIntermediateException(SourceLineNumberCollection.FromFileName(intermediate.Path), "ComplexReference missing required attribute: 'parentId'");
            }
            if (ComplexReferenceChildType.Unknown == childType)
            {
                throw new WixInvalidIntermediateException(SourceLineNumberCollection.FromFileName(intermediate.Path), "Unknown ComplexReferenceChildType type");
            }
            if (null == childId)
            {
                throw new WixInvalidIntermediateException(SourceLineNumberCollection.FromFileName(intermediate.Path), "ComplexReference missing required attribute: 'childId'");
            }

            if (!empty && reader.Read() && XmlNodeType.EndElement != reader.MoveToContent())
            {
                throw new WixInvalidIntermediateException(SourceLineNumberCollection.FromFileName(intermediate.Path), String.Format("Unexpected content while processing 'complexReference': {0}", reader.NodeType.ToString()));
            }

            section.ComplexReferences.Add(new ComplexReference(parentType, parentId, parentLanguage, childType, childId, primary));
        }
Ejemplo n.º 4
0
        /// <summary>
        /// Parse a field from the xml.
        /// </summary>
        /// <param name="reader">XmlReader where the intermediate is persisted.</param>
        internal override void Parse(XmlReader reader)
        {
            Debug.Assert("field" == reader.LocalName);

            bool empty = reader.IsEmptyElement;

            this.baseUri = reader.BaseURI;

            while (reader.MoveToNextAttribute())
            {
                switch (reader.LocalName)
                {
                case "cabinetFileId":
                    this.cabinetFileId = reader.Value;
                    break;

                case "modified":
                    this.Modified = Common.IsYes(SourceLineNumberCollection.FromUri(reader.BaseURI), "field", reader.Name, reader.Value);
                    break;

                case "previousData":
                    this.previousData = reader.Value;
                    break;

                default:
                    if (!reader.NamespaceURI.StartsWith("http://www.w3.org/"))
                    {
                        throw new WixException(WixErrors.UnexpectedAttribute(SourceLineNumberCollection.FromUri(reader.BaseURI), "field", reader.Name));
                    }
                    break;
                }
            }

            if (!empty)
            {
                bool done = false;

                while (!done && reader.Read())
                {
                    switch (reader.NodeType)
                    {
                    case XmlNodeType.Element:
                        throw new WixException(WixErrors.UnexpectedElement(SourceLineNumberCollection.FromUri(reader.BaseURI), "field", reader.Name));

                    case XmlNodeType.CDATA:
                    case XmlNodeType.Text:
                        if (0 < reader.Value.Length)
                        {
                            this.Data = reader.Value;
                        }
                        break;

                    case XmlNodeType.EndElement:
                        done = true;
                        break;
                    }
                }

                if (!done)
                {
                    throw new WixException(WixErrors.ExpectedEndElement(SourceLineNumberCollection.FromUri(reader.BaseURI), "field"));
                }
            }
        }
Ejemplo n.º 5
0
        /// <summary>
        /// Parse a field from the xml.
        /// </summary>
        /// <param name="reader">XmlReader where the intermediate is persisted.</param>
        internal virtual void Parse(XmlReader reader)
        {
            Debug.Assert("field" == reader.LocalName);

            bool empty = reader.IsEmptyElement;

            while (reader.MoveToNextAttribute())
            {
                switch (reader.LocalName)
                {
                case "modified":
                    this.modified = Common.IsYes(SourceLineNumberCollection.FromUri(reader.BaseURI), "field", reader.Name, reader.Value);
                    break;

                case "previousData":
                    this.previousData = reader.Value;
                    break;

                default:
                    if (!reader.NamespaceURI.StartsWith("http://www.w3.org/", StringComparison.Ordinal))
                    {
                        throw new WixException(WixErrors.UnexpectedAttribute(SourceLineNumberCollection.FromUri(reader.BaseURI), "field", reader.Name));
                    }
                    break;
                }
            }

            if (!empty)
            {
                bool done = false;

                while (!done && reader.Read())
                {
                    switch (reader.NodeType)
                    {
                    case XmlNodeType.Element:
                        throw new WixException(WixErrors.UnexpectedElement(SourceLineNumberCollection.FromUri(reader.BaseURI), "field", reader.Name));

                    case XmlNodeType.CDATA:
                    case XmlNodeType.Text:
                    case XmlNodeType.SignificantWhitespace:
                        if (0 < reader.Value.Length)
                        {
                            if (ColumnType.Number == this.columnDefinition.Type && !this.columnDefinition.IsLocalizable)
                            {
                                // older wix files could persist data as a long value (which would overflow an int)
                                // since the Convert class always throws exceptions for overflows, read in integral
                                // values as a long to avoid the overflow, then cast it to an int (this operation can
                                // overflow without throwing an exception inside an unchecked block)
                                this.data = unchecked ((int)Convert.ToInt64(reader.Value, CultureInfo.InvariantCulture));
                            }
                            else
                            {
                                this.data = reader.Value;
                            }
                        }
                        break;

                    case XmlNodeType.EndElement:
                        done = true;
                        break;
                    }
                }

                if (!done)
                {
                    throw new WixException(WixErrors.ExpectedEndElement(SourceLineNumberCollection.FromUri(reader.BaseURI), "field"));
                }
            }
        }
Ejemplo n.º 6
0
        /// <summary>
        /// Processes an XmlReader and builds up the file media information object.
        /// </summary>
        /// <param name="reader">Reader to get data from.</param>
        /// <returns>File media information object.</returns>
        internal static FileMediaInformation Parse(XmlReader reader)
        {
            Debug.Assert("fileMediaInformation" == reader.LocalName);
            string fileId                        = null;
            string directoryId                   = null;
            int    mediaId                       = -1;
            string srcPath                       = null;
            int    rowNumber                     = -1;
            bool   containedInModule             = false;
            int    patchGroup                    = -1;
            int    sequence                      = -1;
            FileCompressionValue fileCompression = FileCompressionValue.NotSpecified;
            bool empty = reader.IsEmptyElement;

            while (reader.MoveToNextAttribute())
            {
                switch (reader.LocalName)
                {
                case "fileId":
                    fileId = reader.Value;
                    break;

                case "directoryId":
                    directoryId = reader.Value;
                    break;

                case "mediaId":
                    mediaId = Convert.ToInt32(reader.Value, CultureInfo.InvariantCulture.NumberFormat);
                    break;

                case "srcPath":
                    srcPath = reader.Value;
                    break;

                case "rowNumber":
                    rowNumber = Convert.ToInt32(reader.Value, CultureInfo.InvariantCulture.NumberFormat);
                    break;

                case "inModule":
                    containedInModule = Common.IsYes(reader.Value, null, "fileMediaInformation", "inModule", fileId);
                    break;

                case "patchGroup":
                    patchGroup = Convert.ToInt32(reader.Value, CultureInfo.InvariantCulture.NumberFormat);
                    break;

                case "sequence":
                    sequence = Convert.ToInt32(reader.Value, CultureInfo.InvariantCulture.NumberFormat);
                    break;

                case "fileCompression":
                    switch (reader.Value)
                    {
                    case "NotSpecified":
                        fileCompression = FileCompressionValue.NotSpecified;
                        break;

                    case "No":
                        fileCompression = FileCompressionValue.No;
                        break;

                    case "Yes":
                        fileCompression = FileCompressionValue.Yes;
                        break;

                    default:
                        throw new WixParseException(String.Format("The fileMediaInformation/@fileCompression attribute contains an unexpected value '{0}'.", reader.Value));
                    }
                    break;

                default:
                    throw new WixParseException(String.Format("The fileMediaInformation element contains an unexpected attribute {0}.", reader.Name));
                }
            }
            if (null == fileId)
            {
                throw new WixParseException("The fileMediaInformation/@fileId attribute was not found; it is required.");
            }
            if (null == directoryId)
            {
                throw new WixParseException("The fileMediaInformation/@directoryId attribute was not found; it is required.");
            }

            if (!empty)
            {
                throw new WixParseException("The fileMediaInformation element contains text or other elements; it cannot.");
            }

            FileMediaInformation fmi = new FileMediaInformation(fileId, directoryId, mediaId, srcPath, rowNumber, fileCompression, null, patchGroup);

            fmi.containedInModule = containedInModule;
            fmi.sequence          = sequence;
            return(fmi);
        }
Ejemplo n.º 7
0
        /// <summary>
        /// Parses table definition from xml reader.
        /// </summary>
        /// <param name="reader">Reader to get data from.</param>
        /// <returns>The TableDefintion represented by the Xml.</returns>
        internal static TableDefinition Parse(XmlReader reader)
        {
            Debug.Assert("tableDefinition" == reader.LocalName);

            bool   empty               = reader.IsEmptyElement;
            bool   createSymbols       = false;
            bool   hasPrimaryKeyColumn = false;
            string name   = null;
            bool   unreal = false;
            bool   bootstrapperApplicationData = false;

            while (reader.MoveToNextAttribute())
            {
                switch (reader.LocalName)
                {
                case "createSymbols":
                    createSymbols = Common.IsYes(SourceLineNumberCollection.FromUri(reader.BaseURI), "createSymbols", reader.Name, reader.Value);
                    break;

                case "name":
                    name = reader.Value;
                    break;

                case "unreal":
                    unreal = Common.IsYes(SourceLineNumberCollection.FromUri(reader.BaseURI), "tableDefinition", reader.Name, reader.Value);
                    break;

                case "bootstrapperApplicationData":
                    bootstrapperApplicationData = Common.IsYes(SourceLineNumberCollection.FromUri(reader.BaseURI), "tableDefinition", reader.Name, reader.Value);
                    break;

                default:
                    if (!reader.NamespaceURI.StartsWith("http://www.w3.org/", StringComparison.Ordinal))
                    {
                        throw new WixException(WixErrors.UnexpectedAttribute(SourceLineNumberCollection.FromUri(reader.BaseURI), "tableDefinition", reader.Name));
                    }
                    break;
                }
            }

            if (null == name)
            {
                throw new WixException(WixErrors.ExpectedAttribute(SourceLineNumberCollection.FromUri(reader.BaseURI), "tableDefinition", "name"));
            }

            TableDefinition tableDefinition = new TableDefinition(name, createSymbols, unreal, bootstrapperApplicationData);

            // parse the child elements
            if (!empty)
            {
                bool done = false;

                while (!done && reader.Read())
                {
                    switch (reader.NodeType)
                    {
                    case XmlNodeType.Element:
                        switch (reader.LocalName)
                        {
                        case "columnDefinition":
                            ColumnDefinition columnDefinition = ColumnDefinition.Parse(reader);
                            tableDefinition.columns.Add(columnDefinition);

                            if (columnDefinition.IsLocalizable)
                            {
                                tableDefinition.localizable = true;
                            }

                            if (columnDefinition.IsPrimaryKey)
                            {
                                hasPrimaryKeyColumn = true;
                            }
                            break;

                        default:
                            throw new WixException(WixErrors.UnexpectedElement(SourceLineNumberCollection.FromUri(reader.BaseURI), "tableDefinition", reader.Name));
                        }
                        break;

                    case XmlNodeType.EndElement:
                        done = true;
                        break;
                    }
                }

                if (!unreal && !bootstrapperApplicationData && !hasPrimaryKeyColumn)
                {
                    throw new WixException(WixErrors.RealTableMissingPrimaryKeyColumn(SourceLineNumberCollection.FromUri(reader.BaseURI), name));
                }

                if (!done)
                {
                    throw new WixException(WixErrors.ExpectedEndElement(SourceLineNumberCollection.FromUri(reader.BaseURI), "tableDefinition"));
                }
            }

            return(tableDefinition);
        }
Ejemplo n.º 8
0
        /// <summary>
        /// Processes an XmlReader and builds up the output object.
        /// </summary>
        /// <param name="reader">Reader to get data from.</param>
        /// <param name="suppressVersionCheck">Suppresses wix.dll version mismatch check.</param>
        /// <param name="path">The path to display in an error message.</param>
        /// <returns>The Output represented by the Xml.</returns>
        private static Output Parse(XmlReader reader, bool suppressVersionCheck, string path)
        {
            Debug.Assert("wixOutput" == reader.LocalName);

            Output output = new Output();

            output.path = path;
            string      entrySectionId = null;
            SectionType sectionType    = SectionType.Unknown;
            Version     objVersion     = null;
            bool        empty          = reader.IsEmptyElement;

            while (reader.MoveToNextAttribute())
            {
                switch (reader.LocalName)
                {
                case "type":
                    switch (reader.Value)
                    {
                    case "Module":
                        output.type = OutputType.Module;
                        sectionType = SectionType.Module;
                        break;

                    case "Product":
                        output.type = OutputType.Product;
                        sectionType = SectionType.Product;
                        break;

                    case "PatchCreation":
                        output.type = OutputType.PatchCreation;
                        sectionType = SectionType.PatchCreation;
                        break;

                    default:
                        throw new WixParseException(String.Format("The wixOutput/@type attribute contains an unexpected value '{0}'.", reader.Value));
                    }
                    break;

                case "codepage":
                    output.codepage = Convert.ToInt32(reader.Value, CultureInfo.InvariantCulture.NumberFormat);
                    break;

                case "compressed":
                    output.compressed = Common.IsYes(reader.Value, null, "wixOutput", reader.Name, null);
                    break;

                case "longFileNames":
                    output.longFileNames = Common.IsYes(reader.Value, null, "wixOutput", reader.Name, null);
                    break;

                case "entrySectionId":
                    entrySectionId = reader.Value;
                    break;

                case "moduleGuid":
                    output.moduleGuid = reader.Value;
                    break;

                case "output":
                    output.path = reader.Value;
                    break;

                case "suppressAdminSequence":
                    output.suppressAdminSequence = Common.IsYes(reader.Value, null, "wixOutput", reader.Name, null);
                    break;

                case "suppressAdvertiseSequence":
                    output.suppressAdvertiseSequence = Common.IsYes(reader.Value, null, "wixOutput", reader.Name, null);
                    break;

                case "suppressUISequence":
                    output.suppressUISequence = Common.IsYes(reader.Value, null, "wixOutput", reader.Name, null);
                    break;

                case "version":
                    objVersion = new Version(reader.Value);
                    break;

                case "xmlns":
                    break;

                default:
                    throw new WixParseException(String.Format("The wixOutput element contains an unexpected attribute {0}.", reader.Name));
                }
            }
            if (null == entrySectionId)
            {
                throw new WixParseException("The wixOutput/@entrySectionId attribute was not found; it is required.");
            }
            if (null != objVersion && !suppressVersionCheck)
            {
                Version currentVersion = Common.OutputFormatVersion;
                if (0 != currentVersion.CompareTo(objVersion))
                {
                    throw new WixVersionMismatchException(currentVersion, objVersion, "Output", output.Path);
                }
            }

            // create a section for all the rows to belong to
            Intermediate intermediate = new Intermediate();

            output.entrySection = new Section(intermediate, entrySectionId, sectionType, output.codepage);

            // loop through the rest of the xml building up the Output object
            if (!empty)
            {
                bool done = false;

                // loop through all the fields in a row
                while (!done && reader.Read())
                {
                    switch (reader.NodeType)
                    {
                    case XmlNodeType.Element:
                        switch (reader.LocalName)
                        {
                        case "outputTable":
                            output.outputTables.Add(OutputTable.Parse(reader, output.entrySection));
                            break;

                        case "importStream":
                            output.importStreams.Add(ImportStream.Parse(reader));
                            break;

                        case "componentsToFeatures":
                        case "featuresToFeatures":
                        case "modulesToFeatures":
                            ParseConnectToFeatures(output, reader);
                            break;

                        case "merge":
                            ParseMerge(output, reader);
                            break;

                        case "fileMediaInformation":
                            output.fileMediaInfoCollection.Add(FileMediaInformation.Parse(reader));
                            break;

                        case "media":
                            ParseMedia(output, reader);
                            break;

                        default:
                            throw new WixParseException(String.Format("The wixOutput element contains an unexpected child element {0}.", reader.Name));
                        }
                        break;

                    case XmlNodeType.EndElement:
                        done = true;
                        break;
                    }
                }

                if (!done)
                {
                    throw new WixParseException("Missing end element while processing the wixOutput element.");
                }
            }

            return(output);
        }
Ejemplo n.º 9
0
        /// <summary>
        /// Parses ActionRows from the Xml reader.
        /// </summary>
        /// <param name="reader">Xml reader that contains serialized ActionRows.</param>
        /// <returns>The parsed ActionRows.</returns>
        internal static WixActionRow[] Parse(XmlReader reader)
        {
            Debug.Assert("action" == reader.LocalName);

            string id            = null;
            string condition     = null;
            bool   empty         = reader.IsEmptyElement;
            int    sequence      = int.MinValue;
            int    sequenceCount = 0;

            SequenceTable[] sequenceTables = new SequenceTable[Enum.GetValues(typeof(SequenceTable)).Length];

            while (reader.MoveToNextAttribute())
            {
                switch (reader.Name)
                {
                case "name":
                    id = reader.Value;
                    break;

                case "AdminExecuteSequence":
                    if (Common.IsYes(SourceLineNumberCollection.FromUri(reader.BaseURI), "action", reader.Name, reader.Value))
                    {
                        sequenceTables[sequenceCount] = SequenceTable.AdminExecuteSequence;
                        ++sequenceCount;
                    }
                    break;

                case "AdminUISequence":
                    if (Common.IsYes(SourceLineNumberCollection.FromUri(reader.BaseURI), "action", reader.Name, reader.Value))
                    {
                        sequenceTables[sequenceCount] = SequenceTable.AdminUISequence;
                        ++sequenceCount;
                    }
                    break;

                case "AdvtExecuteSequence":
                    if (Common.IsYes(SourceLineNumberCollection.FromUri(reader.BaseURI), "action", reader.Name, reader.Value))
                    {
                        sequenceTables[sequenceCount] = SequenceTable.AdvtExecuteSequence;
                        ++sequenceCount;
                    }
                    break;

                case "condition":
                    condition = reader.Value;
                    break;

                case "InstallExecuteSequence":
                    if (Common.IsYes(SourceLineNumberCollection.FromUri(reader.BaseURI), "action", reader.Name, reader.Value))
                    {
                        sequenceTables[sequenceCount] = SequenceTable.InstallExecuteSequence;
                        ++sequenceCount;
                    }
                    break;

                case "InstallUISequence":
                    if (Common.IsYes(SourceLineNumberCollection.FromUri(reader.BaseURI), "action", reader.Name, reader.Value))
                    {
                        sequenceTables[sequenceCount] = SequenceTable.InstallUISequence;
                        ++sequenceCount;
                    }
                    break;

                case "sequence":
                    sequence = Convert.ToInt32(reader.Value, CultureInfo.InvariantCulture);
                    break;

                default:
                    if (!reader.NamespaceURI.StartsWith("http://www.w3.org/"))
                    {
                        throw new WixException(WixErrors.UnexpectedAttribute(SourceLineNumberCollection.FromUri(reader.BaseURI), "action", reader.Name));
                    }
                    break;
                }
            }

            if (null == id)
            {
                throw new WixException(WixErrors.ExpectedAttribute(SourceLineNumberCollection.FromUri(reader.BaseURI), "action", "name"));
            }

            if (int.MinValue == sequence)
            {
                throw new WixException(WixErrors.ExpectedAttribute(SourceLineNumberCollection.FromUri(reader.BaseURI), "action", "sequence"));
            }
            else if (1 > sequence)
            {
                throw new WixException(WixErrors.IntegralValueOutOfRange(SourceLineNumberCollection.FromUri(reader.BaseURI), "action", "sequence", sequence, 1, int.MaxValue));
            }

            if (0 == sequenceCount)
            {
                throw new WixException(WixErrors.ExpectedAttributes(SourceLineNumberCollection.FromUri(reader.BaseURI), "action", "AdminExecuteSequence", "AdminUISequence", "AdvtExecuteSequence", "InstallExecuteSequence", "InstallUISequence"));
            }

            if (!empty && reader.Read() && XmlNodeType.EndElement != reader.MoveToContent())
            {
                throw new WixException(WixErrors.UnexpectedContentNode(SourceLineNumberCollection.FromUri(reader.BaseURI), "action", reader.NodeType.ToString()));
            }

            // create the actions
            WixActionRow[] actionRows = new WixActionRow[sequenceCount];
            for (int i = 0; i < sequenceCount; i++)
            {
                WixActionRow actionRow = new WixActionRow(sequenceTables[i], id, condition, sequence);
                actionRows[i] = actionRow;
            }

            return(actionRows);
        }
Ejemplo n.º 10
0
        /// <summary>
        /// Processes an XmlReader and builds up the feature connection object.
        /// </summary>
        /// <param name="reader">Reader to get data from.</param>
        /// <returns>ConnectToFeature object.</returns>
        internal static ConnectToFeature Parse(XmlReader reader)
        {
            Debug.Assert("connectToFeature" == reader.LocalName);

            string childId                = null;
            string primaryFeature         = null;
            bool   explicitPrimaryFeature = false;
            bool   empty = reader.IsEmptyElement;

            while (reader.MoveToNextAttribute())
            {
                switch (reader.LocalName)
                {
                case "childId":
                    childId = reader.Value;
                    break;

                case "primaryFeature":
                    primaryFeature = reader.Value;
                    break;

                case "explicitPrimaryFeature":
                    explicitPrimaryFeature = Common.IsYes(reader.Value, null, "connectToFeature", reader.Name, childId);
                    break;

                default:
                    throw new WixParseException(String.Format("The connectToFeature element contains an unexpected attribute {0}.", reader.Name));
                }
            }
            if (null == childId)
            {
                throw new WixParseException(String.Format("The connectToFeature/@childId attribute was not found; it is required."));
            }
            if (null == primaryFeature)
            {
                throw new WixParseException(String.Format("The connectToFeature/@primaryFeature attribute was not found; it is required."));
            }

            ConnectToFeature ctf = new ConnectToFeature(null, childId, primaryFeature, explicitPrimaryFeature);

            if (!empty)
            {
                bool done = false;

                // loop through all the fields in a row
                while (!done && reader.Read())
                {
                    switch (reader.NodeType)
                    {
                    case XmlNodeType.Element:
                        switch (reader.LocalName)
                        {
                        case "feature":
                            ctf.connectFeatures.Add(reader.ReadString());
                            break;

                        default:
                            throw new WixParseException(String.Format("The connectToFeature element contains an unexpected child element {0}.", reader.Name));
                        }
                        break;

                    case XmlNodeType.EndElement:
                        done = true;
                        break;
                    }
                }

                if (!done)
                {
                    throw new WixParseException("Missing end element while processing the connectToFeature element.");
                }
            }

            return(ctf);
        }
Ejemplo n.º 11
0
        /// <summary>
        /// Populates the hashtable from the Xml reader.
        /// </summary>
        /// <param name="reader">Xml reader that contains serialized actions.</param>
        private void ParseAction(XmlReader reader)
        {
            string id        = null;
            string condition = null;
            int    sequence  = 0;

            SequenceType[] sequenceTypes = new SequenceType[5];
            int            sequenceCount = 0;

            while (reader.MoveToNextAttribute())
            {
                switch (reader.Name)
                {
                case "name":
                    id = reader.Value;
                    break;

                case "condition":
                    condition = reader.Value;
                    break;

                case "sequence":
                    sequence = Convert.ToInt32(reader.Value);
                    break;

                case "AdminExecuteSequence":
                    if (Common.IsYes(reader.Value, null, reader.Name, null, null))
                    {
                        sequenceTypes[sequenceCount] = SequenceType.adminExecute;
                        ++sequenceCount;
                    }
                    break;

                case "AdminUISequence":
                    if (Common.IsYes(reader.Value, null, reader.Name, null, null))
                    {
                        sequenceTypes[sequenceCount] = SequenceType.adminUI;
                        ++sequenceCount;
                    }
                    break;

                case "AdvtExecuteSequence":
                    if (Common.IsYes(reader.Value, null, reader.Name, null, null))
                    {
                        sequenceTypes[sequenceCount] = SequenceType.advertiseExecute;
                        ++sequenceCount;
                    }
                    break;

                case "InstallExecuteSequence":
                    if (Common.IsYes(reader.Value, null, reader.Name, null, null))
                    {
                        sequenceTypes[sequenceCount] = SequenceType.installExecute;
                        ++sequenceCount;
                    }
                    break;

                case "InstallUISequence":
                    if (Common.IsYes(reader.Value, null, reader.Name, null, null))
                    {
                        sequenceTypes[sequenceCount] = SequenceType.installUI;
                        ++sequenceCount;
                    }
                    break;
                }
            }
            if (null == id)
            {
                throw new ApplicationException("cannot have null id attribute on action element");
            }
            else if (0 == sequence)
            {
                throw new ApplicationException("must have sequence attribute with value greater than zero on action element");
            }
            else if (0 == sequenceCount)
            {
                throw new ApplicationException("must have one sequence allowed on action element");
            }

            // now add all the sequences
            for (int i = 0; i < sequenceCount; i++)
            {
                Action action = new Action(sequenceTypes[i], id, condition, sequence);
                this.actions.Add(String.Concat(sequenceTypes[i].ToString(), id), action);
            }
        }
Ejemplo n.º 12
0
        /// <summary>
        /// Parses a column definition in a table definition.
        /// </summary>
        /// <param name="reader">Reader to get data from.</param>
        /// <returns>The ColumnDefintion represented by the Xml.</returns>
        internal static ColumnDefinition Parse(XmlReader reader)
        {
            Debug.Assert("columnDefinition" == reader.LocalName);

            string               name        = null;
            ColumnType           type        = ColumnType.Unknown;
            int                  length      = -1;
            bool                 primaryKey  = false;
            bool                 symbol      = false;
            bool                 nullable    = false;
            ColumnModularizeType modularize  = ColumnModularizeType.None;
            bool                 unreal      = false;
            bool                 localizable = false;

            bool           minValueSet         = false;
            int            minValue            = 0;
            bool           maxValueSet         = false;
            int            maxValue            = 0;
            string         keyTable            = null;
            bool           keyColumnSet        = false;
            int            keyColumn           = -1;
            ColumnCategory category            = ColumnCategory.Unknown;
            string         possibilities       = null;
            string         description         = null;
            bool           escapeIdtCharacters = false;
            bool           useCData            = false;
            bool           empty = reader.IsEmptyElement;

            // parse the attributes
            while (reader.MoveToNextAttribute())
            {
                switch (reader.LocalName)
                {
                case "name":
                    name = reader.Value;
                    break;

                case "type":
                    switch (reader.Value)
                    {
                    case "string":
                        type = ColumnType.String;
                        break;

                    case "localized":
                        type = ColumnType.Localized;
                        break;

                    case "localizedNumber":
                        type = ColumnType.LocalizedNumber;
                        break;

                    case "number":
                        type = ColumnType.Number;
                        break;

                    case "object":
                        type = ColumnType.Object;
                        break;

                    default:
                        throw new WixParseException(String.Format("The columnDefinition/@type attribute contains an unexpected value '{0}'.", reader.Value));
                    }
                    break;

                case "length":
                    length = Convert.ToInt32(reader.Value, 10);
                    break;

                case "primaryKey":
                    primaryKey = Common.IsYes(reader.Value, null, "columnDefinition", "primaryKey", name);
                    break;

                case "nullable":
                    nullable = Common.IsYes(reader.Value, null, "columnDefinition", "nullable", name);
                    break;

                case "modularize":
                    switch (reader.Value)
                    {
                    case "none":
                        modularize = ColumnModularizeType.None;
                        break;

                    case "column":
                        modularize = ColumnModularizeType.Column;
                        break;

                    case "companionFile":
                        modularize = ColumnModularizeType.CompanionFile;
                        break;

                    case "condition":
                        modularize = ColumnModularizeType.Condition;
                        break;

                    case "controlEventArgument":
                        modularize = ColumnModularizeType.ControlEventArgument;
                        break;

                    case "icon":
                        modularize = ColumnModularizeType.Icon;
                        break;

                    case "property":
                        modularize = ColumnModularizeType.Property;
                        break;

                    case "semicolonDelimited":
                        modularize = ColumnModularizeType.SemicolonDelimited;
                        break;

                    default:
                        throw new WixParseException(String.Format("The columnDefinition/@modularize attribute contains an unexpected value '{0}'.", reader.Value));
                    }
                    break;

                case "symbol":
                    symbol = Common.IsYes(reader.Value, null, "columnDefinition", "symbol", name);
                    break;

                case "unreal":
                    unreal = Common.IsYes(reader.Value, null, "columnDefinition", "unreal", name);
                    break;

                case "localizable":
                    localizable = Common.IsYes(reader.Value, null, "columnDefinition", "localizable", name);
                    break;

                case "minValue":
                    minValueSet = true;
                    minValue    = Convert.ToInt32(reader.Value, 10);
                    break;

                case "maxValue":
                    maxValueSet = true;
                    maxValue    = Convert.ToInt32(reader.Value, 10);
                    break;

                case "keyTable":
                    keyTable = reader.Value;
                    break;

                case "keyColumn":
                    keyColumnSet = true;
                    keyColumn    = Convert.ToInt32(reader.Value, 10);
                    break;

                case "category":
                    switch (reader.Value)
                    {
                    case "text":
                        category = ColumnCategory.Text;
                        break;

                    case "upperCase":
                        category = ColumnCategory.UpperCase;
                        break;

                    case "lowerCase":
                        category = ColumnCategory.LowerCase;
                        break;

                    case "integer":
                        category = ColumnCategory.Integer;
                        break;

                    case "doubleInteger":
                        category = ColumnCategory.DoubleInteger;
                        break;

                    case "timeDate":
                        category = ColumnCategory.TimeDate;
                        break;

                    case "identifier":
                        category = ColumnCategory.Identifier;
                        break;

                    case "property":
                        category = ColumnCategory.Property;
                        break;

                    case "filename":
                        category = ColumnCategory.Filename;
                        break;

                    case "wildCardFilename":
                        category = ColumnCategory.WildCardFilename;
                        break;

                    case "path":
                        category = ColumnCategory.Path;
                        break;

                    case "paths":
                        category = ColumnCategory.Paths;
                        break;

                    case "anyPath":
                        category = ColumnCategory.AnyPath;
                        break;

                    case "defaultDir":
                        category = ColumnCategory.DefaultDir;
                        break;

                    case "regPath":
                        category = ColumnCategory.RegPath;
                        break;

                    case "formatted":
                        category = ColumnCategory.Formatted;
                        break;

                    case "template":
                        category = ColumnCategory.Template;
                        break;

                    case "condition":
                        category = ColumnCategory.Condition;
                        break;

                    case "guid":
                        category = ColumnCategory.Guid;
                        break;

                    case "version":
                        category = ColumnCategory.Version;
                        break;

                    case "language":
                        category = ColumnCategory.Language;
                        break;

                    case "binary":
                        category = ColumnCategory.Binary;
                        break;

                    case "customSource":
                        category = ColumnCategory.CustomSource;
                        break;

                    case "cabinet":
                        category = ColumnCategory.Cabinet;
                        break;

                    case "shortcut":
                        category = ColumnCategory.Shortcut;
                        break;

                    default:
                        throw new WixParseException(String.Format("The columnDefinition/@category attribute contains an unexpected value '{0}'.", reader.Value));
                    }
                    break;

                case "set":
                    possibilities = reader.Value;
                    break;

                case "description":
                    description = reader.Value;
                    break;

                case "escapeIdtCharacters":
                    escapeIdtCharacters = Common.IsYes(reader.Value, null, "columnDefinition", reader.LocalName, name);
                    break;

                case "useCData":
                    useCData = Common.IsYes(reader.Value, null, "columnDefinition", reader.LocalName, name);
                    break;

                default:
                    throw new WixParseException(String.Format("The columnDefinition element contains an unexpected attribute '{0}'.", reader.Name));
                }
            }

            // parse the child elements (there should be none)
            if (!empty)
            {
                bool done = false;

                while (!done && reader.Read())
                {
                    switch (reader.NodeType)
                    {
                    case XmlNodeType.Element:
                        throw new WixParseException(String.Format("The columnDefinition element contains an unexpected child element {0}.", reader.Name));

                    case XmlNodeType.EndElement:
                        done = true;
                        break;
                    }
                }

                if (!done)
                {
                    throw new WixParseException("Missing end element while processing the columnDefinition element.");
                }
            }

            return(new ColumnDefinition(name, type, length, primaryKey, symbol, nullable, modularize, unreal, localizable, minValueSet, minValue, maxValueSet, maxValue, keyTable, keyColumnSet, keyColumn, category, possibilities, description, escapeIdtCharacters, useCData));
        }
Ejemplo n.º 13
0
        /// <summary>
        /// Parse a localization string.
        /// </summary>
        /// <param name="reader">XmlReader where the localization file is persisted.</param>
        /// <param name="tableDefinitions">Collection containing TableDefinitions to use when loading the localization file.</param>
        /// <param name="localization">The localization being parsed.</param>
        private static void ParseString(XmlReader reader, TableDefinitionCollection tableDefinitions, Localization localization)
        {
            Debug.Assert("String" == reader.LocalName);

            bool empty = reader.IsEmptyElement;
            SourceLineNumberCollection sourceLineNumbers = SourceLineNumberCollection.FromUri(reader.BaseURI);

            string id          = null;
            bool   overridable = false;
            string value       = String.Empty; // default this value to the empty string

            while (reader.MoveToNextAttribute())
            {
                switch (reader.LocalName)
                {
                case "Id":
                    id = reader.Value;
                    break;

                case "Overridable":
                    overridable = Common.IsYes(sourceLineNumbers, "String", reader.Name, reader.Value);
                    break;

                default:
                    if (!reader.NamespaceURI.StartsWith("http://www.w3.org/"))
                    {
                        throw new WixException(WixErrors.UnexpectedAttribute(sourceLineNumbers, "String", reader.Name));
                    }
                    break;
                }
            }

            if (!empty)
            {
                bool done = false;

                while (!done && reader.Read())
                {
                    switch (reader.NodeType)
                    {
                    case XmlNodeType.Element:
                        throw new WixException(WixErrors.UnexpectedElement(sourceLineNumbers, "String", reader.Name));

                    case XmlNodeType.CDATA:
                    case XmlNodeType.Text:
                        if (0 < reader.Value.Length)
                        {
                            value = reader.Value;
                        }
                        break;

                    case XmlNodeType.EndElement:
                        done = true;
                        break;
                    }
                }

                if (!done)
                {
                    throw new WixException(WixErrors.ExpectedEndElement(sourceLineNumbers, "String"));
                }
            }

            if (null == id)
            {
                throw new WixException(WixErrors.ExpectedAttribute(sourceLineNumbers, "String", "Id"));
            }

            WixVariableRow wixVariableRow = new WixVariableRow(sourceLineNumbers, tableDefinitions["WixVariable"]);

            wixVariableRow.Id          = id;
            wixVariableRow.Overridable = overridable;
            wixVariableRow.Value       = value;

            WixVariableRow existingWixVariableRow = (WixVariableRow)localization.variables[id];

            if (null == existingWixVariableRow || (existingWixVariableRow.Overridable && !overridable))
            {
                localization.variables.Add(id, wixVariableRow);
            }
            else if (!overridable)
            {
                throw new WixException(WixErrors.DuplicateLocalizationIdentifier(sourceLineNumbers, id));
            }
        }
Ejemplo n.º 14
0
        /// <summary>
        /// Parses table definition from xml reader.
        /// </summary>
        /// <param name="reader">Reader to get data from.</param>
        /// <returns>The TableDefintion represented by the Xml.</returns>
        internal static TableDefinition Parse(XmlReader reader)
        {
            Debug.Assert("tableDefinition" == reader.LocalName);

            string name   = null;
            bool   unreal = false;
            bool   empty  = reader.IsEmptyElement;

            // parse the attributes
            while (reader.MoveToNextAttribute())
            {
                switch (reader.LocalName)
                {
                case "name":
                    name = reader.Value;
                    break;

                case "unreal":
                    unreal = Common.IsYes(reader.Value, null, "tableDefinition", reader.Name, name);
                    break;

                case "xmlns":
                    break;

                default:
                    throw new WixParseException(String.Format("The tableDefinition element contains an unexpected attribute '{0}'.", reader.Name));
                }
            }

            if (null == name)
            {
                throw new WixParseException("The tableDefinition/@name attribute was not found; it is required.");
            }

            TableDefinition tableDefinition = new TableDefinition(name, unreal);

            // parse the child elements
            if (!empty)
            {
                bool done = false;

                while (!done && reader.Read())
                {
                    switch (reader.NodeType)
                    {
                    case XmlNodeType.Element:
                        switch (reader.LocalName)
                        {
                        case "columnDefinition":
                            tableDefinition.columns.Add(ColumnDefinition.Parse(reader));
                            break;

                        default:
                            throw new WixParseException(String.Format("The tableDefinition element contains an unexpected child element {0}.", reader.Name));
                        }
                        break;

                    case XmlNodeType.EndElement:
                        done = true;
                        break;
                    }
                }

                if (!done)
                {
                    throw new WixParseException("Missing end element while processing the tableDefinition element.");
                }
            }

            return(tableDefinition);
        }