Example #1
0
File: SDF.cs Project: Tkachov/sdf
        /// <summary>
        ///     Returns new SDF hierarchy where all elements matching to given SDF Path are replaced with a copy of given SDF.
        ///     If root element matches the given path, given SDF is returned (not a copy of it).
        /// </summary>
        /// <param name="path">SDF Path for elements to match to.</param>
        /// <param name="newValue">SDF to replaced matching elements with.</param>
        /// <returns>Reference to either updated <c>this</c> or <c>newValue</c>.</returns>
        public SDF Replace(string path, SDF newValue)
        {
            var topMatches = FindTopMatches(path);

            foreach (var m in topMatches)
            {
                if (m.Parent == null)
                {
                    // if root is being replaced
                    return(newValue);
                }

                var oldValue = m.Value;
                var parent   = m.Parent.Value as Node;               // parents can only be nodes
                if (parent == null)
                {
                    throw new InvalidDataException("Element has parent which is not a Node (impossible).");
                }

                var index = parent.Children.IndexOf(oldValue);
                if (index != -1)
                {
                    parent.Children[index] = newValue.DeepCopy();
                }
                else                     // not a child, then must be an attribute
                {
                    var found = false;
                    foreach (var pair in parent.Attributes)
                    {
                        if (pair.Value == oldValue)
                        {
                            parent.Attributes[pair.Key] = newValue.DeepCopy();
                            found = true;
                            break;
                        }
                    }

                    if (!found)
                    {
                        throw new InvalidDataException("Cannot replace element because element's parent doesn't have it neither as a child nor as an attribute.");
                    }
                }
            }

            return(this);
        }
Example #2
0
File: SDF.cs Project: Tkachov/sdf
        /// <summary>
        ///     Inserts a clone of <c>value</c> as a child to all elements matching given SDF Path at position <c>index</c>.
        /// </summary>
        /// <param name="path">SDF Path for elements to match to.</param>
        /// <param name="index">Position to insert into.</param>
        /// <param name="value">Value to be inserted.</param>
        public void InsertAt(string path, int index, SDF value)
        {
            var matches = Find(path);

            foreach (var match in matches)
            {
                var node = match.Value as Node;
                if (node == null)
                {
                    throw new InvalidDataException("Cannot insert a child into something but a Node.");
                }

                node.Children.Insert(index, value.DeepCopy());
            }
        }
Example #3
0
File: SDF.cs Project: Tkachov/sdf
        /// <summary>
        ///     Adds a clone of <c>value</c> as a child to all elements matching given SDF Path.
        ///     Can only apply to nodes.
        /// </summary>
        /// <param name="path">SDF Path for elements to match to.</param>
        /// <param name="value">Value of the added child.</param>
        public void AddChild(string path, SDF value)
        {
            var matches = Find(path);

            foreach (var match in matches)
            {
                var node = match.Value as Node;
                if (node == null)
                {
                    throw new InvalidDataException("Cannot add a child to something but a Node.");
                }

                node.Children.Add(value.DeepCopy());
            }
        }
Example #4
0
File: SDF.cs Project: Tkachov/sdf
        /// <summary>
        ///     Adds an attribute with <c>attributeName</c> name and <c>value</c> value to all elements matching given SDF Path.
        ///     Can only apply to nodes.
        ///     Throws an exception if attribute with given name already exists on a matching element.
        /// </summary>
        /// <param name="path">SDF Path for elements to match to.</param>
        /// <param name="attributeName">Name of the added attribute.</param>
        /// <param name="value">Value of the added attribute.</param>
        public void AddAttribute(string path, string attributeName, SDF value)
        {
            var matches = Find(path);

            foreach (var match in matches)
            {
                var node = match.Value as Node;
                if (node == null)
                {
                    throw new InvalidDataException("Cannot add an attribute to something but a Node.");
                }

                if (node.Attributes.ContainsKey(attributeName))
                {
                    throw new InvalidDataException("Cannot add an attribute, because attribute with such name already exists.");
                }

                node.Attributes[attributeName] = value.DeepCopy();
            }
        }
Example #5
0
File: SDF.cs Project: Tkachov/sdf
        /// <summary>
        ///     Inserts a clone of <c>value</c> after all elements matching given SDF Path.
        ///     Throws an exception if adding next to root element.
        /// </summary>
        /// <param name="path">SDF Path for elements to match to.</param>
        /// <param name="value">Value to be inserted.</param>
        public void InsertAfter(string path, SDF value)
        {
            var matches = Find(path);

            foreach (var match in matches)
            {
                if (match.Parent == null)
                {
                    throw new InvalidDataException("Cannot add something next to root element.");
                }

                var node = match.Parent.Value as Node;
                if (node == null)
                {
                    throw new InvalidDataException("Cannot insert a child into something but a Node.");
                }

                node.InsertAfterChild(match.Value, value.DeepCopy());
            }
        }