/// <summary>
        /// Creates a collection of new OpenXmlElement from the element type IDs.
        /// </summary>
        /// <param name="parent">The parent element.</param>
        /// <param name="elementIds">The IDs of the children elements.</param>
        /// <returns>A collection of new OpenXmlElements.</returns>
        /// <remarks>
        /// This method use reflection to create the elements. So be aware the performance tax.
        /// </remarks>
        internal static ICollection <OpenXmlElement> CreateChildrenElementsByIds(this OpenXmlElement parent, IEnumerable <int> elementIds)
        {
            Debug.Assert(parent is OpenXmlCompositeElement);
            Debug.Assert(elementIds != null);

            List <OpenXmlElement> childElements = new List <OpenXmlElement>();

            if (elementIds.Count() > 0)
            {
                // use reflection
                var childElementTypeAttributes = parent.GetType().GetTypeInfo().GetCustomAttributes <ChildElementInfoAttribute>();

                foreach (ChildElementInfoAttribute childElementTypeAttribute in childElementTypeAttributes)
                {
                    Type childType = childElementTypeAttribute.ElementType;

                    var childElement = (OpenXmlElement)System.Activator.CreateInstance(childType);

                    foreach (var id in elementIds)
                    {
                        if (childElement.ElementTypeId == id)
                        {
                            childElements.Add(childElement);
                        }
                    }
                }
            }

            return(childElements);
        }
        /// <summary>
        /// Get position index in same type in the ChildElements of it's parent element.
        /// </summary>
        /// <param name="element">The OpenxmlElement.</param>
        /// <returns>The position index in same type element in parent.</returns>
        internal static int GetXPathIndex(this OpenXmlElement element)
        {
            if (element == null)
            {
                throw new ArgumentNullException(nameof(element));
            }

            if (element.Parent == null)
            {
                return(1);
            }

            int count = 1;

            if (element is OpenXmlMiscNode)
            {
                return(1);
            }

            if (element is OpenXmlUnknownElement)
            {
                foreach (var child in element.Parent.ChildElements)
                {
                    if (element == child)
                    {
                        return(count);
                    }

                    if (child is OpenXmlUnknownElement &&
                        child.NamespaceUri == element.NamespaceUri &&
                        child.LocalName == element.LocalName)
                    {
                        count++;
                    }
                }
            }
            else
            {
                Type type = element.GetType();

                foreach (var child in element.Parent.ChildElements)
                {
                    if (element == child)
                    {
                        return(count);
                    }

                    if (type == child.GetType())
                    {
                        count++;
                    }
                }
            }

            Debug.Assert(false);
            return(count);
        }
        internal static bool CanContainChild(this OpenXmlElement parent, OpenXmlElement child)
        {
            if (parent is OpenXmlCompositeElement)
            {
                foreach (var element in parent.Metadata.Children.Elements)
                {
                    if (element.Type.GetTypeInfo().IsAssignableFrom(child.GetType().GetTypeInfo()))
                    {
                        return(true);
                    }
                }
            }

            return(false);
        }
예제 #4
0
        internal static bool CanContainsChild(this OpenXmlElement parent, OpenXmlElement child)
        {
            if (parent is OpenXmlCompositeElement)
            {
                // use reflection
                var childElementTypeAttributes = parent.GetType().GetTypeInfo().GetCustomAttributes <ChildElementInfoAttribute>();

                foreach (ChildElementInfoAttribute childElementTypeAttribute in childElementTypeAttributes)
                {
                    if (childElementTypeAttribute.ElementType.GetTypeInfo().IsAssignableFrom(child.GetType().GetTypeInfo()))
                    {
                        return(true);
                    }
                }
            }
            return(false);
        }
        internal static bool CanContainsChild(this OpenXmlElement parent, OpenXmlElement child)
        {
            if (parent is OpenXmlCompositeElement)
            {
                // use reflection
                var childElementTypeAttributes = Attribute.GetCustomAttributes(parent.GetType(), typeof(ChildElementInfoAttribute));

                foreach (ChildElementInfoAttribute childElementTypeAttribute in childElementTypeAttributes)
                {
                    if (childElementTypeAttribute.ElementType.IsInstanceOfType(child))
                    {
                        return(true);
                    }
                }
            }
            return(false);
        }
        /// <summary>
        /// Adds the specified element to the element if it is a known child. This adds the element in the correct location according to the schema.
        /// </summary>
        /// <param name="newChild">The OpenXmlElement element to append.</param>
        /// <param name="throwOnError">A flag to indicate if the method should throw if the child could not be added.</param>
        /// <returns>Success if the element was added, otherwise <c>false</c>.</returns>
        public bool AddChild(OpenXmlElement newChild, bool throwOnError = true)
        {
            if (newChild is null)
            {
                if (throwOnError)
                {
                    throw new ArgumentNullException(nameof(newChild));
                }

                return(false);
            }

            var wasAdded = Metadata.Particle.Set(this, newChild, newChild?.GetType());

            if (throwOnError && !wasAdded)
            {
                throw new InvalidOperationException(ExceptionMessages.ElementIsNotChild);
            }

            return(wasAdded);
        }