/// <summary>
        /// Uses the provided path elements to find an list element at the specified index, and returns a property
        /// to the element, or to a child property of that element.
        /// </summary>
        /// <param name="pathElements">Path elements representing field names and keys to look for.</param>
        /// <param name="elementIdx">Index in the <paramref name="pathElements"/> array to start the search at.</param>
        /// <returns>Property representing the final path element, or null if not found (list index is out of range, or 
        ///          property with that path doesn't exist).</returns>
        internal SerializableProperty FindProperty(PropertyPathElement[] pathElements, int elementIdx)
        {
            int arrayIdx;
            if (string.IsNullOrEmpty(pathElements[elementIdx].key))
                arrayIdx = 0;
            else
            {
                if (!int.TryParse(pathElements[elementIdx].key, out arrayIdx))
                    return null;
                else
                {
                    if (arrayIdx < 0 || arrayIdx >= GetLength())
                        return null;
                }
            }

            SerializableProperty property = GetProperty(arrayIdx);
            if (elementIdx == (pathElements.Length - 1))
                return property;

            return property.FindProperty(pathElements, elementIdx + 1);
        }
Beispiel #2
0
        /// <summary>
        /// Searches the object, and all child objects for a field or entry with the specified name.
        /// </summary>
        /// <param name="path">Slash separated path with field name(s) to search for. If a field contains an array, list or
        ///                    a dictionary append its name with a "[x]" where x is the element index in the array/list, or
        ///                    a key name (surrounded by "") in case of a dictionary. Only primitive dictionary keys are
        ///                    supported.
        ///
        ///                    Example path: subObject/myDictionary["someElement"]/theArray[4]/fieldToGet
        ///                    </param>
        /// <returns>Property you can use for reading or modifying the property, or null if not found.</returns>
        public SerializableProperty FindProperty(string path)
        {
            if (path == null)
            {
                return(null);
            }

            string trimmedPath = path.Trim('/');

            string[] pathEntries = trimmedPath.Split('/');
            PropertyPathElement[] pathElements = new PropertyPathElement[pathEntries.Length];
            for (int i = 0; i < pathEntries.Length; i++)
            {
                string entry = pathEntries[i];
                if (string.IsNullOrEmpty(entry))
                {
                    return(null);
                }

                pathElements[i] = new PropertyPathElement();

                int startIdx   = 0;
                int nameEndIdx = 0;
                int endIdx     = entry.Length - 1;
                if (entry[entry.Length - 1] == ']')
                {
                    bool foundKey = false;
                    for (int j = 0; j < entry.Length - 1; j++)
                    {
                        if (entry[j] == '[')
                        {
                            startIdx   = j;
                            nameEndIdx = j;
                            foundKey   = true;
                        }
                    }

                    // Trim string quotes, if they exist
                    if (startIdx < (endIdx - 1) && entry[startIdx + 1] == '"')
                    {
                        startIdx++;
                    }

                    if (endIdx > (startIdx + 1) && entry[endIdx - 1] == '"')
                    {
                        endIdx--;
                    }

                    if (foundKey)
                    {
                        pathElements[i].name = entry.Substring(0, nameEndIdx);
                        pathElements[i].key  = entry.Substring(startIdx + 1, endIdx - (startIdx + 1));
                    }
                    else
                    {
                        pathElements[i].name = entry;
                    }
                }
                else
                {
                    pathElements[i].name = entry;
                }
            }

            return(FindProperty(pathElements, 0));
        }