private static IPropertyContainer?ParseXmlElement(
            XElement objectElement,
            IObjectSchema objectSchema,
            IXmlParserSettings settings,
            IXmlParserContext context,
            IMutablePropertyContainer?container = null)
        {
            if (objectElement.HasElements)
            {
                container ??= new MutablePropertyContainer();

                foreach (XElement propertyElement in objectElement.Elements())
                {
                    string    elementName  = settings.GetElementName(propertyElement);
                    string    propertyName = settings.StringProvider.GetString(elementName);
                    IProperty?property     = objectSchema.GetProperty(propertyName);

                    if (propertyElement.HasElements)
                    {
                        IObjectSchema propertyInternalSchema = context.GetOrCreateNewSchemaCached(property).ToObjectSchema();

                        IPropertyContainer?internalObject = ParseXmlElement(propertyElement, propertyInternalSchema, settings, context);
                        if (internalObject != null && internalObject.Count > 0)
                        {
                            if (settings.SetSchemaForObjects)
                            {
                                internalObject.SetSchema(propertyInternalSchema);
                            }

                            if (property == null)
                            {
                                property = new Property <IPropertyContainer>(propertyName)
                                           .SetIsNotFromSchema()
                                           .SetSchema(propertyInternalSchema);

                                if (objectSchema is IMutableObjectSchema mutableObjectSchema)
                                {
                                    property = mutableObjectSchema.AddProperty(property);
                                }
                            }

                            IPropertyValue propertyValue = settings.PropertyValueFactory.CreateUntyped(property, internalObject);
                            container.Add(propertyValue);

                            // Validate property.
                            if (settings.ValidateOnParse)
                            {
                                ValidateProperty(context, container, property, propertyElement);
                            }
                        }
                    }
                    else
                    {
                        if (property != null && property.Type == typeof(IPropertyContainer))
                        {
                            // Composite object, no value.
                            bool isNullAllowed = property.GetOrEvaluateNullability().IsNullAllowed;
                            if (!isNullAllowed)
                            {
                                context.Messages.AddError(
                                    $"Property '{property.Name}' can not be null but xml element has no value.{GetXmlLineInfo(propertyElement)}");
                            }

                            continue;
                        }

                        if (property == null)
                        {
                            property = new Property <string>(propertyName)
                                       .SetIsNotFromSchema();

                            if (objectSchema is IMutableObjectSchema mutableObjectSchema)
                            {
                                property = mutableObjectSchema.AddProperty(property);
                            }
                        }

                        IValueParser valueParser = context.GetParserCached(property);
                        if (valueParser != EmptyParser.Instance)
                        {
                            string elementValue = propertyElement.Value;

                            // Parse value.
                            IParseResult parseResult = valueParser.ParseUntyped(elementValue);

                            if (parseResult.IsSuccess)
                            {
                                // Add property to container.
                                object?        parsedValue   = parseResult.ValueUntyped;
                                IPropertyValue propertyValue = settings.PropertyValueFactory.CreateUntyped(property, parsedValue);
                                container.Add(propertyValue);

                                // Validate property.
                                if (settings.ValidateOnParse)
                                {
                                    ValidateProperty(context, container, property, propertyElement);
                                }
                            }
                            else
                            {
                                string?parseResultErrorMessage = parseResult.Error?.FormattedMessage;
                                string parseResultError        = parseResultErrorMessage != null ? $" Error: '{parseResultErrorMessage}'." : string.Empty;
                                string errorMessage            = $"Property '{property.Name}' failed to parse from string '{elementValue}'.{parseResultError}{GetXmlLineInfo(propertyElement)}";
                                context.Messages.AddError(errorMessage);
                            }
                        }
                        else
                        {
                            string errorMessage = $"Property '{property.Name}' can not be parsed because no parser found for type {property.Type}.{GetXmlLineInfo(propertyElement)}";
                            context.Messages.AddError(errorMessage);
                        }
                    }
                }

                return(container);
            }

            return(null);
        }