Example #1
0
 public void Enumerable_Create1_SiblingAdd()
 {
     XElement root = new XElement("root", new XElement("NodeA", new XElement("Id", "a")));
     XElement notexpected = new XElement("root");
     XPathString xpath = new XPathString("//NodeA[Id={0}]/ChildA[@key={1}]", "A", "1");
     var actual = cXPath.Enumerable(root, xpath, true);
     Assert.AreNotEqual(root.ToString(), notexpected.ToString()); // root was changed
 }
Example #2
0
 public void Enumerable_CreateNode_RootUnchanged()
 {
     XElement root = new XElement("root");
     XElement expected = new XElement("root");
     XPathString xpath = new XPathString("//NodeA[Id={0}]/ChildA[@key={1}]", "A", "1");
     var actual = cXPath.Enumerable(root, xpath, true);
     Assert.AreEqual(root.ToString(), expected.ToString()); // root remains unchanged
 }
Example #3
0
 public void Enumerable_CreateNode_RootUnchanged1()
 {
     XElement root = new XElement("root");
     XElement expected = new XElement("ChildA", new XAttribute("key", "1"));
     XPathString xpath = new XPathString("//NodeA[Id={0}]/ChildA[@key={1}]", "A", "1");
     XElement actual = cXPath.Enumerable(root, xpath, true).First();
     Assert.AreEqual(actual.ToString(), expected.ToString());
 }
Example #4
0
 public void IsXPath_PathWithBrackets()
 {
     string path = "part[key=value]";
     object[] values = null;
     XPathString target = new XPathString(path, values);
     bool actual, expected = true;
     actual = target.IsXPath;
     Assert.AreEqual(expected, actual);
 }
Example #5
0
 public void IsXPath_JustAPath()
 {
     string path = "part/path/nodes";
     object[] values = new object[] { };
     XPathString target = new XPathString(path, values);
     bool actual, expected = false;
     actual = target.IsXPath;
     Assert.AreEqual(expected, actual);
 }
Example #6
0
 public void Elements_currentNodeEqualsValue()
 {
     XPathString path = new XPathString("[.='Mike']");
     XPath_Bracket target = new XPath_Bracket(path);
     IEnumerable<XElement> elements = root.Descendants();
     var expected = root.Descendants()
         .Where(xe => xe.Value == "Mike").ToArray();
     var actual = target.Elements(elements).ToArray();
     CollectionAssert.AreEqual(expected, actual);
 }
Example #7
0
        public void Combine()
        {
            string path = "pair[path/to/@Key={0}]/Items/Item[Name={1}]/Date";
            object[] values = new object[] { 2, "Martin" };
            XPathString xp = new XPathString(path, values);

            string expected = "pair[path/to/@Key={0}]/Items/Item[Name={1}]";
            XPathString actual = XPathString.Combine(xp.PathSegments.Take(3));
            Assert.AreEqual(expected, actual.Format);
            CollectionAssert.AreEqual(values, actual.Values);
        }
Example #8
0
        public XPath_Bracket(XPathString path)
        {
            string text = path.Format;
            XPath = path.Text.TrimStart('[').TrimEnd(']');
            text = text.TrimStart('[').TrimEnd(']');
            AndOr = text.Contains(" and ");

            // need new XPathString() that has brackets removed.
            XPathString[] paths = new XPathString(true, text, path.Values)
                .Split(new string[] { " and ", " or " }, StringSplitOptions.RemoveEmptyEntries, true);
            Parts = paths.Select(s => new XPath_Part(s)).ToArray();
        }
Example #9
0
 public void Enumerable_Create1_SiblingAdd2()
 {
     // Add not-found NodeA as a sibling to another NodeA
     XElement root = new XElement("root", new XElement("NodeA", new XElement("Id", "a")));
     XElement expected = new XElement("root", new XElement("NodeA", new XElement("Id", "a")));
     expected.Add(new XElement("NodeA",
         new XElement("Id", "A"),
         new XElement("ChildA", new XAttribute("key", "1"))
         ));
     XPathString xpath = new XPathString("//NodeA[Id={0}]/ChildA[@key={1}]", "A", "1");
     var actual = cXPath.Enumerable(root, xpath, true);
     Assert.AreEqual(root.ToString(), expected.ToString()); // root was changed
 }
Example #10
0
 public void Enumerable_Create1_ChildAdd1()
 {
     // Add not-found key element to existing NodeA element
     XElement root = new XElement("root", new XElement("NodeA", new XElement("Id", "A")));
     XElement expected = new XElement("root",
         new XElement("NodeA",
             new XElement("Id", "A"),
             new XElement("ChildA", new XAttribute("key", "1"))
         )
     );
     XPathString xpath = new XPathString("//NodeA[Id={0}]/ChildA[@key={1}]", "A", "1");
     var actual = cXPath.Enumerable(root, xpath, true);
     Assert.AreEqual(root.ToString(), expected.ToString()); // root was changed
 }
Example #11
0
 public void XPath_Bracket_Constructor()
 {
     XPathString path = new XPathString("[.='Mike']");
     XPath_Bracket target = new XPath_Bracket(path);
     Assert.AreEqual(target.Parts.Length, 1);
     var part = target.Parts[0];
     Assert.AreEqual(part.ElementAt, false);
     Assert.AreEqual(part.Equal, true);
     Assert.AreEqual(part.Function, null);
     Assert.AreEqual(part.GreaterThan, false);
     Assert.AreEqual(part.GreaterThanOrEqual, false);
     Assert.AreEqual(part.IsValueAttribute, false);
     Assert.AreEqual(part.Key, ".");
     Assert.AreEqual(part.KVP, true);
     Assert.AreEqual(part.LessThan, false);
     Assert.AreEqual(part.LessThanOrEqual, false);
     Assert.AreEqual(part.NotEqual, false);
     Assert.AreEqual(part.Value, "Mike");
 }
Example #12
0
 public void XPath_Part_KVP_GTEqualR()
 {
     XPathString path = new XPathString("[{0}>=to]", 0);
     XPath_Bracket target = new XPath_Bracket(path);
     Assert.AreEqual(target.Parts.Length, 1);
     var part = target.Parts[0]; // XPath_Part becomes "to < {0}"
     Assert.AreEqual(part.ElementAt, false);
     Assert.AreEqual(part.IsValueAttribute, false);
     Assert.AreEqual(part.KVP, true);
     Assert.AreEqual(null, part.Function);
     Assert.AreEqual(part.Equal, false);
     Assert.AreEqual(part.GreaterThan, false);
     Assert.AreEqual(part.GreaterThanOrEqual, false);
     Assert.AreEqual(part.LessThan, true);
     Assert.AreEqual(part.LessThanOrEqual, false);
     Assert.AreEqual(part.NotEqual, false);
     Assert.AreEqual(part.Key, "to");
     Assert.AreEqual(part.Value, 0);
 }
Example #13
0
 public void IsXPath_PathWithoutBrackets()
 {
     string path = "//part";
     object[] values = null;
     XPathString target = new XPathString(path, values);
     bool actual, expected = false;
     actual = target.IsXPath;
     Assert.AreEqual(expected, actual);
 }
Example #14
0
 public void XPath_Part_KVP_Right()
 {
     /*
      * Swaps the expression to be [@to >= {0}]
      * So we compare for > and >=
      */
     XPathString path = new XPathString("[{0} < @to]", 0);
     XPath_Bracket target = new XPath_Bracket(path);
     Assert.AreEqual(target.Parts.Length, 1);
     var part = target.Parts[0]; // XPath_Part
     Assert.AreEqual(part.ElementAt, false);
     Assert.AreEqual(null, part.Function);
     Assert.AreEqual(part.IsValueAttribute, true);
     Assert.AreEqual(part.KVP, true);
     Assert.AreEqual(part.Equal, true);
     Assert.AreEqual(part.GreaterThan, true);
     Assert.AreEqual(part.GreaterThanOrEqual, true);
     Assert.AreEqual(part.LessThan, false);
     Assert.AreEqual(part.LessThanOrEqual, false);
     Assert.AreEqual(part.NotEqual, false);
     Assert.AreEqual(part.Key, "to");
     Assert.AreEqual(part.Value, 0);
 }
Example #15
0
 public void Split_overrideEquals()
 {
     string path = "pair[path/to/@Key={0}]/Items/Item[Name={1}]/Date";
     object[] values = new object[] { 2, "Martin" };
     XPathString target = new XPathString(path, values);
     XPathString[] expected = new[]{
         new XPathString("pair[path/to/@Key={0}]", 2),
         new XPathString("Items"),
         new XPathString("Item[Name={0}]", "Martin"),
         new XPathString("Date")
     };
     XPathString[] actual;
     actual = target.Split();
     CollectionAssert.AreEqual(expected, actual);
 }
Example #16
0
 public void XPathElementTest()
 {
     XPathString path = new XPathString("pair[@Key={0}]/Items/Item[Name={1}]", 2, "Martin");
     bool create = false;
     XElement expected = root.Elements("pair")
         .Where(x => ((int)x.Attribute("Key")) == 2)
         .SelectMany(x => x.Element("Items").Elements("Item"))
         .Where(x => ((string)x.Element("Name")) == "Martin")
         .FirstOrDefault();
     XElement actual;
     actual = XPathExtensions.XPathElement(root, path, create);
     Assert.AreEqual(expected, actual);
 }
Example #17
0
 public void XPathStringConstructor_EmptyPath()
 {
     string path = string.Empty;
     object[] values = null;
     XPathString target = new XPathString(path, values);
 }
Example #18
0
 public void ToPaths_Same()
 {
     string path = "same";
     object[] values = null;
     XPathString target = new XPathString(path, values);
     XPathString[] expected = new[] { target };
     XPathString[] actual = target.ToPaths(true, path);
     CollectionAssert.AreEqual(expected, actual);
 }
Example #19
0
 public void XPathStringConstructor_Path_EmbeddedValues()
 {
     string path = "pair[@Key=2]/Items/Item[Name='Martin']/Date";
     object[] values = null;
     XPathString target = new XPathString(path, values);
     string actual, expected = "pair[@Key=2]/Items/Item[Name='Martin']/Date";
     actual = target.Text;
     Assert.AreEqual(expected, actual);
 }
Example #20
0
 public void XPathStringConstructor_NullPath()
 {
     string path = null;
     object[] values = null;
     XPathString target = new XPathString(path, values);
 }
Example #21
0
        /// <summary>
        /// Get the elements of a path "path/to/node" or "path[to/node/@attribute>=20.50]".
        /// <remarks>
        /// <para>See XPath docs for help on using [number][key=value]
        /// - syntax (http://www.w3.org/TR/xpath/)</para>
        /// </remarks>
        /// </summary>
        /// <param name="source"></param>
        /// <param name="path"></param>
        /// <param name="create">create path if it doesn't exist?</param>
        /// <exception cref="ArgumentOutOfRangeException" />
        public static IEnumerable<XElement> Enumerable(XElement source, XPathString path, bool create)
        {
            IEnumerable<XElement> enumerableXElement;

            if (null == path)
                throw new ArgumentNullException("Path cannot be null.");

            if (!path.IsRelative)
                source = source.Root();
            List<XElement> list = new[] { source }.ToList();
            for (int i = 0; i < path.PathSegments.Length; i++)
            {
                List<XElement> newList = new List<XElement>();
                XPathString xpathString = path.PathSegments[i];
                //bool last = (i + 1) == path.PathSegments.Length;

                if (xpathString.IsXPath)
                {
                    bool foundOne = false;
                    list.ForEach(xElement =>
                    {
                        enumerableXElement = ParseInternal(xElement, xpathString);
                        if (null != enumerableXElement)
                        {
                            newList.AddRange(enumerableXElement.ToList());
                            foundOne = true;
                        }
                    });
                    if (foundOne)
                    {
                        list = newList;
                        continue;
                    }
                }
                list.ForEach(xElement => newList.AddRange(PartToElements(xElement, xpathString)));
                list = newList;
            }

            // If the node wasn't found and we were asked to create it, do the best we can
            // If it is a simple search, then we won't be able to place the node and it will be dangling (without a parent node)
            if (list.Count == 0 && create)
            {
                // Find parent element if we can, and plug in the new node there
                XElement parent = null;
                foreach (var seg in path.PathSegments.Take(path.PathSegments.Length - 1))
                    parent = (parent ?? source).XPathElement(seg, create);
                // If not found, try finding a sibling without search parameters
                // and use it's parent.
                if (null == parent)
                {
                    XPathString clean = path.Clone_NoBrackets();
                    XElement sibling = source.XPathElement(clean, false);
                    if (null != sibling)
                        parent = sibling.Parent;
                }

                // Using last segment in XPath, create the node that is missing
                var segment = path.PathSegments.Last();
                XElement node = new XElement(segment.Name);
                if (null != parent)
                    parent.Add(node);

                // Add any child element's or attribute's that were requested in the search
                foreach (var b in segment.Brackets)
                {
                    foreach (var part in b.Parts)
                    {
                        if (!part.Equal) continue;
                        if (part.IsValueAttribute)
                            node.Add(new XAttribute(part.Key, part.Value));
                        else
                            node.Add(new XElement(part.Key, part.Value));
                    }
                }
                list.Add(node);
            }
            return list;
        }
Example #22
0
        public void SplitInternalTest()
        {
            string path = "pair[path/to/@Key={0}]/Items/Item[Name={1}]/Date";
            object[] values = new object[] { 2, "Martin" };
            XPathString xp = new XPathString(path, values);

            PrivateObject param0 = new PrivateObject(xp);
            XPathString_Accessor target = new XPathString_Accessor(param0);
            string[] expected = new string[] {
                "pair[path/to/@Key={0}]",
                "Items",
                "Item[Name={1}]",
                "Date"
            };
            string[] actual;
            actual = target.SplitInternal();
            CollectionAssert.AreEqual(expected, actual);
        }
Example #23
0
 public void XPathStringConstructor_Path_ExternalValues()
 {
     string path = "pair[@Key={0}]/Items/Item[Name={1}]/Date";
     object[] values = new object[] { 2, "Martin" };
     XPathString target = new XPathString(path, values);
     string actual, expected = "pair[@Key=2]/Items/Item[Name=Martin]/Date";
     actual = target.Text;
     Assert.AreEqual(expected, actual);
 }
Example #24
0
        public XPath_Part(XPathString text)
        {
            self = text;
            string format = text.Format;
            if (Equal = format.Contains('='))
            {
                SetKVP(format, '=');
                if (NotEqual = Key.EndsWith("!"))
                    Key = Key.TrimEnd('!');
                else if (LessThan = Key.EndsWith("<"))
                    Key = Key.TrimEnd('<');
                else if (GreaterThan = Key.EndsWith(">"))
                    Key = Key.TrimEnd('>');
                if (!LessThan && !GreaterThan)
                    SwapSymbol = false; // don't swap Equal to false or NotEqual to true
            }
            else if (LessThan = format.Contains("<"))
            {
                SetKVP(format, '<');
            }
            else if (GreaterThan = format.Contains(">"))
            {
                SetKVP(format, '>');
            }
            if (SwapSymbol)
            {
                LessThan = !LessThan;
                GreaterThan = !GreaterThan;
                Equal = !Equal;
            }
            if (!string.IsNullOrEmpty(Key))
                Key = Key.Trim();

            {
                Match functionMatch = Regex.Match(format, @"^\w+[^\(]*\([^\)]*\)"); // last(), starts-with(key, value)
                if (functionMatch.Success)
                {
                    string func = functionMatch.Value;
                    string function = func.Split('(')[0].ToLower();
                    switch (function)
                    {
                        case "contains":
                            Function = new Contains(this);
                            break;
                        case "ends-with":
                            Function = new EndsWith(this);
                            break;
                        case "last":
                            ElementAt = true;
                            Key = functionMatch.Value;
                            Match digits = Regex.Match(format, @"\d+$"); // ddd
                            int i;
                            if (digits.Success && int.TryParse(digits.Value, out i))
                                _Value = i;
                            else
                                _Value = 0;

                            break;
                        case "local-name":
                            Function = new LocalName(this);
                            break;
                        case "max":
                        case "min":
                            Function = new MinMax(this, func);
                            break;
                        case "name":
                            Function = new Name(this);
                            break;
                        case "string-length":
                            Function = new StringLength(this);
                            break;
                        case "starts-with":
                            Function = new StartsWith(this);
                            break;
                        case "substring":
                            Function = new Substring(this);
                            break;
                    }

                    if (null != Function)
                    {
                        string kvp = Regex.Match(func, @"\(([^\)]*)\)").Groups[1].Value;//.TrimStart('(').TrimEnd(')');
                        if (!string.IsNullOrEmpty(kvp))
                            Function.Args = kvp.Split(',').Select(s => Format(s)).ToArray();

                        if (Function.HasKVP)
                        {
                            if (!string.IsNullOrEmpty(kvp) || Function.ArgumentsRequired)
                            {
                                string[] parts = kvp.Split(',');
                                try
                                {
                                    if (null != Function.NodeSet)
                                    {
                                        Key = Function.NodeSet;
                                        Value = parts[1 - Function.NodeSet.Index];
                                    }
                                    else
                                    {
                                        Key = parts[0];
                                        Value = parts[1];
                                    }
                                }
                                catch (IndexOutOfRangeException)
                                {
                                    if (Function.ArgumentsValueRequired)
                                        throw new ArgumentException(string.Format(
                                            "Syntax {0}(key, value):  Invalid {0}({1})", func.Split('(')[0], kvp));
                                }
                            }
                            else
                                Key = string.Empty;
                        }
                        else if (Function.Args.Length > 0)
                            Key = Function.Args[0].ToString();
                        else
                            Key = string.Empty;

                        if (Function.IsEqual)
                            Equal = true;
                    }
                }
            }

            if (null == Key)
            {
                // is this a [0] or [{0}] format?
                int i;
                object value = Format(format);
                if (ElementAt = value is int)
                {
                    Value = (int)value;
                    return;
                }
                if (ElementAt = int.TryParse(format, out i))
                {
                    Value = i;
                    return;
                }
                Key = value.ToString();
            }

            if (IsValueAttribute = Key.StartsWith("@"))
                Key = Key.Substring(1);

            if (Value is string && !valueIsString)
            {
                decimal d;
                if (decimal.TryParse((string)Value, out d))
                    _Value = d;
            }
        }
Example #25
0
 public void XPathString_Clone_NoBrackets()
 {
     XPathString xpath = new XPathString("//Site[Id={0}]/add[@key={1}]", "C", "landingName2");
     XPathString actual = xpath.Clone_NoBrackets();
     XPathString expected = new XPathString("//Site/add");
     Assert.AreEqual(actual.Text, expected.Text);
     Assert.AreEqual(actual.IsRelative, expected.IsRelative);
     Assert.AreEqual(actual.IsElements, expected.IsElements);
 }
Example #26
0
 public void XPath_Bracket_Constructor2()
 {
     XPathString path = new XPathString("[min(Value2/Value, {0})]", 0);
     XPath_Bracket target = new XPath_Bracket(path);
     Assert.AreEqual(target.Parts.Length, 1);
     var part = target.Parts[0];
     Assert.AreEqual(part.ElementAt, false);
     Assert.AreEqual(part.Equal, true);
     Assert.AreNotEqual(null, part.Function);
     Assert.IsInstanceOfType(part.Function, typeof(MinMax));
     Assert.AreEqual(part.GreaterThan, false);
     Assert.AreEqual(part.GreaterThanOrEqual, false);
     Assert.AreEqual(part.IsValueAttribute, false);
     Assert.AreEqual(part.Key, "Value2/Value");
     Assert.AreEqual(part.KVP, false);
     Assert.AreEqual(part.LessThan, false);
     Assert.AreEqual(part.LessThanOrEqual, false);
     Assert.AreEqual(part.NotEqual, false);
     Assert.AreEqual(part.Value, 0);
 }
Example #27
0
        private static IEnumerable<XElement> ParseInternal(XElement contextNode, XPathString part)
        {
            IEnumerable<XElement> elements = PartToElements(contextNode, part);
            foreach (XPath_Bracket bracket in part.Brackets)
                elements = bracket.Elements(elements);

            return elements;
        }
Example #28
0
 private static IEnumerable<XElement> PartToElements(XElement contextNode, XPathString xp)
 {
     string name = xp.Name;
     bool star = false;
     if (star = name.Contains('*'))
     {
         string[] parts = name.Split('*');
         if (parts.Length > 2)
             throw new ArgumentException("Invalid name: " + name);
         name = parts[0];
     }
     IEnumerable<XElement> elements;
     if (xp.IsElements)
     {
         if (string.IsNullOrEmpty(name) || star)
             elements = contextNode.Elements();
         else
             elements = contextNode.GetElements(name);
     }
     else
     {
         if (string.IsNullOrEmpty(name) || star)
             elements = contextNode.Descendants();
         else
             elements = contextNode.GetDescendants(name);
     }
     if (star && !string.IsNullOrEmpty(name))
         elements = elements.Where(x => x.Name.LocalName.StartsWith(name));
     return elements;
 }
Example #29
0
 public string XPathString_ConvertTo(string value)
 {
     return(XPathString.ConvertTo(value));
 }