Ejemplo n.º 1
0
        /// <summary>
        /// Parses a single CLR value out of an XML element.
        /// </summary>
        /// <param name="type">The destination type.</param>
        /// <param name="xObject">The XObject containing the value.</param>
        /// <param name="directoryName">The name of the directory where external files can be found.</param>
        /// <returns>The CLR value of the given XML node.</returns>
        static Object ParseValue(Type type, XObject xObject, String directoryName)
        {
            // This will evaluate a literal text object as the value.
            if (xObject is XText)
            {
                XText xText = xObject as XText;
                return(ScriptLoader.ConvertValue(typeof(String), xText.Value));
            }

            // This will interpret an element as a value.
            if (xObject is XElement)
            {
                // This element holds special instructions for the parameter.
                XElement xElement = xObject as XElement;

                // Translate the element type into an Enum.
                parameterElementType parameterElementType = parameterElementType.None;
                if (!ScriptLoader.parameterElementDictionary.TryGetValue(xElement.Name, out parameterElementType))
                {
                    parameterElementType = parameterElementType.None;
                }

                // Common variables used below.
                XAttribute pathAttribute;
                String     path;

                // This will convert the element according to the kind of element it is.
                switch (parameterElementType)
                {
                case parameterElementType.Value:

                    // This will convert a simple text value into the CLR equivalent.
                    return(ConvertValue(ScriptLoader.GetElementType(typeof(String), xElement), xElement));

                case parameterElementType.Load:

                    // This will load a resource file as a Base64 string.
                    pathAttribute = xElement.Attribute("path");
                    path          = Path.IsPathRooted(pathAttribute.Value) ? pathAttribute.Value : Path.Combine(directoryName, pathAttribute.Value);
                    using (FileStream fileStream = new FileStream(path, FileMode.Open, FileAccess.Read))
                    {
                        Byte[] binaryData = new Byte[fileStream.Length];
                        fileStream.Read(binaryData, 0, Convert.ToInt32(fileStream.Length));
                        return(ScriptLoader.ConvertValue(type, Convert.ToBase64String(binaryData)));
                    }

                case parameterElementType.Import:

                    // This will load an XML file as a text string.
                    pathAttribute = xElement.Attribute("path");
                    path          = Path.IsPathRooted(pathAttribute.Value) ? pathAttribute.Value : Path.Combine(directoryName, pathAttribute.Value);
                    XDocument xDocument = XDocument.Load(path);
                    return(ScriptLoader.ConvertValue(type, xDocument.ToString()));
                }
            }

            // Any node that can't be parsed is assumed to be a DBNull value.
            return(DBNull.Value);
        }
Ejemplo n.º 2
0
 /// <summary>
 /// Convert text to a CLR object based on the target datatype.
 /// </summary>
 /// <param name="type">The target datatype.</param>
 /// <param name="element">The xml element.</param>
 /// <returns>The CLR equivalent of the given value.</returns>
 static Object ConvertValue(Type type, XElement element)
 {
     if (element.IsEmpty)
     {
         return(DBNull.Value);
     }
     else
     {
         return(ScriptLoader.ConvertValue(type, element.Value));
     }
 }
Ejemplo n.º 3
0
        /// <summary>
        /// Converts an XElement describing a value to a native CLR value.
        /// </summary>
        /// <param name="type">The target datatype.</param>
        /// <param name="parameterElement">An XElement containing a String representation of a value.</param>
        /// <param name="directoryName">The directory where external files can be found.</param>
        /// <returns>The native CLR value of the described value.</returns>
        static Object ConvertElement(Type type, XElement parameterElement, String directoryName)
        {
            // If the target parameter is an array, then construct a vector parameter.
            if (type == typeof(Object[]))
            {
                // The values can be found in a single attribute of the 'parameter' element or be listed as children.  This list collects both methods of describing
                // values and constructs a single array when all elements and attributes are parsed.
                List <Object> valueList = new List <Object>();

                // An attribute can be used to desribe a value.  An optional 'Type' attribute can specify what type of conversion is used to evaluate the CLR value.
                XAttribute valueAttribute = parameterElement.Attribute("value");
                if (valueAttribute != null)
                {
                    valueList.Add(ScriptLoader.ConvertValue(ScriptLoader.GetElementType(typeof(String), parameterElement), valueAttribute.Value));
                }

                // It is possible to specify the value using the content of an XML element or through an "import" statement.  This will cycle through any nodes of
                // the parameter looking for additional nodes containing the data for the parameter.
                foreach (XObject xObject in parameterElement.Nodes())
                {
                    // This uses the element content as the value for the parameter.
                    if (xObject is XText)
                    {
                        XText xText = xObject as XText;
                        valueList.Add(ConvertValue(typeof(String), xText.Value));
                    }

                    // Elements can be nested inside the parameter element to greater detail to the parameter.
                    if (xObject is XElement)
                    {
                        // This element holds special instructions for the parameter.
                        XElement xElement = xObject as XElement;

                        // Values for a key can be specified as child elements of the parameter.
                        if (xElement.Name == "value")
                        {
                            valueList.Add(ConvertValue(GetElementType(typeof(String), xElement), xElement.Value));
                        }

                        // This special instruction allows the value of a parameter to come from an external file.  This is used primary to load XML content into a
                        // record.
                        if (xElement.Name == "import")
                        {
                            XAttribute xAttribute = xElement.Attribute("path");
                            String     path       = Path.IsPathRooted(xAttribute.Value) ? xAttribute.Value : Path.Combine(directoryName, xAttribute.Value);
                            XDocument  xDocument  = XDocument.Load(path);
                            valueList.Add(ConvertValue(type, xDocument.ToString()));
                        }

                        // A 'load' element will read a binary resource into a byte array.
                        if (xElement.Name == "load")
                        {
                            XAttribute xAttribute = xElement.Attribute("path");
                            String     path       = Path.IsPathRooted(xAttribute.Value) ? xAttribute.Value : Path.Combine(directoryName, xAttribute.Value);
                            Byte[]     binaryData;
                            using (FileStream fileStream = new FileStream(path, FileMode.Open, FileAccess.Read))
                            {
                                binaryData = new Byte[fileStream.Length];
                                fileStream.Read(binaryData, 0, Convert.ToInt32(fileStream.Length));
                            }
                            return(ConvertValue(type, Convert.ToBase64String(binaryData)));
                        }
                    }
                }

                // This array is most often used as a key to find a record in a table.
                return(valueList.ToArray());
            }
            else
            {
                // If the XML specifies an override for the native data type of the parameter, make sure that the new value's type is compatible with the parameter.
                Type originalType = type;
                type = ScriptLoader.GetElementType(type, parameterElement);
                if (type != originalType && !type.IsSubclassOf(originalType))
                {
                    throw new Exception(String.Format("Can't cast a parameter of type {0} to {1}.", type, originalType));
                }

                // It is possible to specify the value using the content of an XML element or through an "import" statement.  This will cycle through any nodes of
                // the parameter looking for additional nodes containing the data for the parameter.  Of course, for a scalar, there is only a single value that
                // can be returned, so we'll take the first element we find that converts into a value.
                foreach (XObject xObject in parameterElement.DescendantNodes())
                {
                    return(ScriptLoader.ParseValue(type, xObject, directoryName));
                }

                // If no elements are specified, then we'll simply convert the attribute into a value for this parameter.  This is by far the most common method of
                // providing values for parameter.
                XAttribute valueAttribute = parameterElement.Attribute("value");
                return(valueAttribute == null ? DBNull.Value : ScriptLoader.ConvertValue(type, valueAttribute.Value));
            }
        }