/// <summary>
        /// Generates a <see cref="AttributeDefinitionString"/> object from its XML representation.
        /// </summary>
        /// <param name="reader">
        /// an instance of <see cref="XmlReader"/>
        /// </param>
        public override void ReadXml(XmlReader reader)
        {
            base.ReadXml(reader);

            while (reader.Read())
            {
                if (reader.MoveToContent() == XmlNodeType.Element && reader.LocalName == "ALTERNATIVE-ID")
                {
                    var alternativeId = new AlternativeId(this);
                    alternativeId.ReadXml(reader);
                }

                if (reader.MoveToContent() == XmlNodeType.Element && reader.LocalName == "DATATYPE-DEFINITION-STRING-REF")
                {
                    var reference = reader.ReadElementContentAsString();

                    var datatypeDefinition = (DatatypeDefinitionString)this.SpecType.ReqIFContent.DataTypes.SingleOrDefault(x => x.Identifier == reference);
                    this.Type = datatypeDefinition;
                }

                // read the default value if any
                if (reader.MoveToContent() == XmlNodeType.Element && reader.LocalName == "ATTRIBUTE-VALUE-STRING")
                {
                    this.DefaultValue = new AttributeValueString(this);
                    using (var valuesubtree = reader.ReadSubtree())
                    {
                        valuesubtree.MoveToContent();
                        this.DefaultValue.ReadXml(valuesubtree);
                    }
                }
            }
        }
        /// <summary>
        /// Sets the <see cref="DatatypeDefinitionString"/>
        /// </summary>
        /// <param name="datatypeDefinition">
        /// The instance of <see cref="DatatypeDefinitionString"/> that is to be set.
        /// </param>
        protected override void SetDatatypeDefinition(DatatypeDefinition datatypeDefinition)
        {
            if (datatypeDefinition.GetType() != typeof(DatatypeDefinitionString))
            {
                throw new ArgumentException("datatypeDefinition must of type DatatypeDefinitionString");
            }

            this.Type = (DatatypeDefinitionString)datatypeDefinition;
        }
        /// <summary>
        /// Asynchronously generates a <see cref="AttributeDefinitionString"/> object from its XML representation.
        /// </summary>
        /// <param name="reader">
        /// an instance of <see cref="XmlReader"/>
        /// </param>
        /// <param name="token">
        /// A cancellation token that can be used by other objects or threads to receive notice of cancellation.
        /// </param>
        internal override async Task ReadXmlAsync(XmlReader reader, CancellationToken token)
        {
            base.ReadXml(reader);

            while (await reader.ReadAsync())
            {
                if (token.IsCancellationRequested)
                {
                    token.ThrowIfCancellationRequested();
                }

                if (await reader.MoveToContentAsync() == XmlNodeType.Element)
                {
                    switch (reader.LocalName)
                    {
                    case "ALTERNATIVE-ID":
                        var alternativeId = new AlternativeId(this);
                        alternativeId.ReadXml(reader);
                        break;

                    case "DATATYPE-DEFINITION-STRING-REF":
                        var reference = await reader.ReadElementContentAsStringAsync();

                        var datatypeDefinition = (DatatypeDefinitionString)this.SpecType.ReqIFContent.DataTypes.SingleOrDefault(x => x.Identifier == reference);
                        this.Type = datatypeDefinition;

                        if (datatypeDefinition == null)
                        {
                            this.logger.LogTrace("The DatatypeDefinitionString:{reference} could not be found and has been set to null on AttributeDefinitionString:{Identifier}", reference, Identifier);
                        }

                        break;

                    case "ATTRIBUTE-VALUE-STRING":
                        this.DefaultValue = new AttributeValueString(this, this.loggerFactory);
                        using (var valueSubtree = reader.ReadSubtree())
                        {
                            await valueSubtree.MoveToContentAsync();

                            await this.DefaultValue.ReadXmlAsync(valueSubtree, token);
                        }
                        break;
                    }
                }
            }
        }