Ejemplo n.º 1
0
        public override bool Equals(object?other)
        {
            if (other == null)
            {
                return(false);
            }

            if (!(other is Fb2Container otherContainer))
            {
                return(false);
            }

            if (!base.Equals(otherContainer))
            {
                return(false);
            }

            var actualContent = content;
            var otherContent  = otherContainer.content;
            var sameContent   = actualContent.Count == otherContent.Count &&
                                actualContent.SequenceEqual(otherContent);

            var result = sameContent &&
                         CanContainText == otherContainer.CanContainText &&
                         AllowedElements.SequenceEqual(otherContainer.AllowedElements);

            return(result);
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Adds given node to <see cref="Content"/>.
        /// </summary>
        /// <param name="node">Child node to add to Content.</param>
        /// <returns>Current container.</returns>
        /// <exception cref="ArgumentNullException"></exception>
        /// <exception cref="InvalidNodeException"></exception>
        /// <exception cref="UnexpectedNodeException"></exception>
        public Fb2Container AddContent(Fb2Node node)
        {
            if (node == null)
            {
                throw new ArgumentNullException(nameof(node));
            }

            if (!Fb2NodeFactory.IsKnownNode(node))
            {
                throw new InvalidNodeException(node);
            }

            var nodeName   = node.Name;
            var isTextNode = node is TextItem;

            if (isTextNode && !CanContainText)
            {
                throw new UnexpectedNodeException(Name, nodeName);
            }

            if (!AllowedElements.Contains(nodeName) && !isTextNode)
            {
                throw new UnexpectedNodeException(Name, nodeName);
            }

            if (isTextNode)
            {
                return(TryMergeTextContent((node as TextItem) !.Content));
            }

            node.Parent = this;
            if (node.NodeMetadata == null && NodeMetadata?.DefaultNamespace != null) // copy parent default namespace to prevent serialization issues
            {
                node.NodeMetadata = new Fb2NodeMetadata(NodeMetadata?.DefaultNamespace);
            }

            content.Add(node);
            return(this);
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Container node loading mechanism. Loads attributes and sequentially calls `Load` on all child nodes.
        /// </summary>
        /// <param name="node">Node to load as Fb2Container</param>
        /// <param name="preserveWhitespace">Indicates if whitespace chars (\t, \n, \r) should be preserved. By default `false`.</param>
        /// <param name="loadUnsafe">Indicates whether "Unsafe" children should be loaded. By default `true`. </param>
        public override void Load(
            [In] XNode node,
            [In] Fb2Container?parentNode = null,
            bool preserveWhitespace      = false,
            bool loadUnsafe            = true,
            bool loadNamespaceMetadata = true)
        {
            base.Load(node, parentNode, preserveWhitespace, loadUnsafe, loadNamespaceMetadata);

            var element = node as XElement;

            if (element == null || element.IsEmpty)
            {
                return;
            }

            var nodes = element.Nodes()
                        .Where(n =>
            {
                if (n.NodeType == XmlNodeType.Text)
                {
                    return(true);
                }

                var isElement = n.NodeType == XmlNodeType.Element;
                if (!isElement)
                {
                    return(false);
                }

                var elementNode   = n as XElement;
                var nodeLocalName = elementNode.Name.LocalName;
                return(!nodeLocalName.EqualsIgnoreCase(ElementNames.FictionText) &&
                       Fb2NodeFactory.IsKnownNodeName(nodeLocalName));
            })
                        .ToList();

            var nodesCount = nodes.Count;

            if (nodesCount == 0)
            {
                return;
            }

            for (int i = 0; i < nodesCount; i++)
            {
                var validNode = nodes[i];

                string localName = validNode.NodeType == XmlNodeType.Element ?
                                   ((XElement)validNode).Name.LocalName.ToLowerInvariant() :
                                   ElementNames.FictionText;

                var isUnsafe = validNode.NodeType == XmlNodeType.Text ?
                               !CanContainText :
                               !AllowedElements.Contains(localName);

                if (isUnsafe && !loadUnsafe)
                {
                    continue;
                }

                var elem = Fb2NodeFactory.GetNodeByName(localName);
                elem.Load(validNode, this, preserveWhitespace, loadUnsafe, loadNamespaceMetadata);
                elem.IsUnsafe = isUnsafe;

                content.Add(elem);
            }
        }