public object Execute(ParameterList parameters, FunctionContextContainer context)
            {
                Guid xsltFunctionId = this._xsltFunction.Id;

                if (_FunctionCalls == null)
                {
                    lock (_lock)
                    {
                        if (_FunctionCalls == null)
                        {
                            _FunctionCalls = RenderHelper.GetValidatedFunctionCalls(xsltFunctionId);
                        }
                    }
                }

                TransformationInputs transformationInput = RenderHelper.BuildInputDocument(_FunctionCalls, parameters, false);

                XDocument newTree = new XDocument();

                using (XmlWriter writer = new LimitedDepthXmlWriter(newTree.CreateWriter()))
                {
                    XslCompiledTransform xslTransformer = GetXslCompiledTransform();

                    XsltArgumentList transformArgs = new XsltArgumentList();
                    XslExtensionsManager.Register(transformArgs);

                    if (transformationInput.ExtensionDefinitions != null)
                    {
                        foreach (IXsltExtensionDefinition extensionDef in transformationInput.ExtensionDefinitions)
                        {
                            transformArgs.AddExtensionObject(extensionDef.ExtensionNamespace.ToString(), extensionDef.EntensionObjectAsObject);
                        }
                    }

                    xslTransformer.Transform(transformationInput.InputDocument.CreateReader(), transformArgs, writer);
                }

                if (this._xsltFunction.OutputXmlSubType == "XHTML")
                {
                    return(new XhtmlDocument(newTree));
                }
                return(newTree.Root);
            }
        private static TransformationInputs BuildInputDocument2(List <NamedFunctionCall> namedFunctions, Dictionary <string, object> inputParameters, List <KeyValuePair <string, XElement> > evaluatedParameterList, List <KeyValuePair <string, IXsltExtensionDefinition> > xslExtensions, bool addDetailedComments)
        {
            var transformationInputs = new TransformationInputs();

            // NOTE: Attribute attributes from "xsi" namespaces aren't used
            // XElement inputRoot = XElement.Parse(string.Format(@"<in:inputs xmlns:in=""{0}"" xmlns:xsi=""{1}"" xmlns:xsd=""{2}"" />", XsltInput10, Namespaces.Xsi, Namespaces.Xsd));

            XElement inputRoot = XElement.Parse(@"<in:inputs xmlns:in=""{0}"" />".FormatWith(XsltInput10));

            transformationInputs.InputDocument = inputRoot;

            // Adding XSL extensions
            if (xslExtensions.Count > 0)
            {
                foreach (KeyValuePair <string, IXsltExtensionDefinition> xslExtension in xslExtensions)
                {
                    IXsltExtensionDefinition extensionDefinition = xslExtension.Value;

                    transformationInputs.ExtensionDefinitions = transformationInputs.ExtensionDefinitions ?? new List <IXsltExtensionDefinition>();
                    transformationInputs.ExtensionDefinitions.Add(extensionDefinition);

                    if (addDetailedComments)
                    {
                        inputRoot.Add(new XComment(string.Format(" Input Parameter '{0}' has been registered as an Xslt Entension Object. Methods on '{1}' can be called using the namespace '{2}' and format 'prefix:MethodName( arguments )'. ", xslExtension.Key, extensionDefinition.EntensionObjectAsObject.GetType().FullName, extensionDefinition.ExtensionNamespace)));
                    }
                }
            }

            // Adding input parameters
            if (evaluatedParameterList.Count > 0)
            {
                foreach (KeyValuePair <string, XElement> parameter in evaluatedParameterList)
                {
                    if (addDetailedComments)
                    {
                        inputRoot.Add(new XComment(string.Format(" Input Parameter, XPath /in:inputs/in:param[@name='{0}'] ", parameter.Key)));
                    }
                    inputRoot.Add(parameter.Value);
                }
            }

            if (namedFunctions.Count > 0)
            {
                var functionCallResults        = new object[namedFunctions.Count];
                var functionCallExecutionTimes = new long[namedFunctions.Count];

                for (int i = 0; i < namedFunctions.Count; i++)
                {
                    FunctionContextContainer functionContextContainer = new FunctionContextContainer(inputParameters);

                    var       namedFunctionCall  = namedFunctions[i];
                    object    result             = null;
                    Stopwatch executionStopwatch = Stopwatch.StartNew();
                    try
                    {
                        result = GetFunctionCallResult(functionContextContainer, namedFunctionCall, addDetailedComments);

                        executionStopwatch.Stop();
                    }
                    catch (Exception ex)
                    {
                        throw new InvalidOperationException(string.Format("Failed to execute function with local name '{0}'", namedFunctionCall.Name), ex);
                    }

                    functionCallResults[i]        = result;
                    functionCallExecutionTimes[i] = executionStopwatch.ElapsedMilliseconds;
                }
                ;


                for (int i = 0; i < namedFunctions.Count; i++)
                {
                    object result = functionCallResults[i];

                    if (result is IXsltExtensionDefinition)
                    {
                        IXsltExtensionDefinition extensionDefinition = (IXsltExtensionDefinition)result;
                        transformationInputs.ExtensionDefinitions = transformationInputs.ExtensionDefinitions ?? new List <IXsltExtensionDefinition>();
                        transformationInputs.ExtensionDefinitions.Add(extensionDefinition);

                        if (addDetailedComments)
                        {
                            string name = namedFunctions[i].Name;
                            inputRoot.Add(new XComment(string.Format(" Function call result '{0}' has been registered as an Xslt Entension Object. ", name, extensionDefinition.ExtensionNamespace)));
                            inputRoot.Add(new XComment(string.Format(" Extension methods can be called using the namespace '{1}'. ", name, extensionDefinition.ExtensionNamespace)));
                            inputRoot.Add(new XComment(" The following methods exist: "));
                            foreach (MethodInfo mi in extensionDefinition.EntensionObjectAsObject.GetType().GetMethods().Where(m => m.DeclaringType != typeof(object)))
                            {
                                string paramsInfo     = string.Join(", ", mi.GetParameters().Select(p => string.Format("{0} {1}", p.ParameterType.Name, p.Name)).ToArray());
                                string returnTypeName = (mi.ReturnType != null ? mi.ReturnType.Name : "void");
                                inputRoot.Add(new XComment(string.Format(" {0} ns:{1}({2}) ", returnTypeName, mi.Name, paramsInfo)));
                            }
                        }
                    }
                    else
                    {
                        Verify.That(result is XElement, "Function call result had to be selialized as XElement");

                        if (addDetailedComments)
                        {
                            string xpathAppend = FindElementXPathAppend(result);

                            inputRoot.Add(new XComment(string.Format(" Function Call Result ({0} ms), XPath /in:inputs/in:result[@name='{1}']{2} ", functionCallExecutionTimes[i], namedFunctions[i].Name, xpathAppend)));
                        }

                        inputRoot.Add(result as XElement);
                    }
                }
            }

            return(transformationInputs);
        }
Exemple #3
0
        private static TransformationInputs BuildInputDocument2(List<NamedFunctionCall> namedFunctions, Dictionary<string, object> inputParameters, List<KeyValuePair<string, XElement>> evaluatedParameterList, List<KeyValuePair<string, IXsltExtensionDefinition>> xslExtensions, bool addDetailedComments)
        {
            var transformationInputs = new TransformationInputs();

            // NOTE: Attribute attributes from "xsi" namespaces aren't used
            // XElement inputRoot = XElement.Parse(string.Format(@"<in:inputs xmlns:in=""{0}"" xmlns:xsi=""{1}"" xmlns:xsd=""{2}"" />", XsltInput10, Namespaces.Xsi, Namespaces.Xsd));

            XElement inputRoot = XElement.Parse(@"<in:inputs xmlns:in=""{0}"" />".FormatWith(XsltInput10));

            transformationInputs.InputDocument = inputRoot;

            // Adding XSL extensions
            if(xslExtensions.Count > 0)
            {
                foreach (KeyValuePair<string, IXsltExtensionDefinition> xslExtension in xslExtensions)
                {
                    IXsltExtensionDefinition extensionDefinition = xslExtension.Value;

                    transformationInputs.ExtensionDefinitions = transformationInputs.ExtensionDefinitions ?? new List<IXsltExtensionDefinition>();
                    transformationInputs.ExtensionDefinitions.Add(extensionDefinition);

                    if (addDetailedComments)
                    {
                        inputRoot.Add(new XComment(string.Format(" Input Parameter '{0}' has been registered as an Xslt Entension Object. Methods on '{1}' can be called using the namespace '{2}' and format 'prefix:MethodName( arguments )'. ", xslExtension.Key, extensionDefinition.EntensionObjectAsObject.GetType().FullName, extensionDefinition.ExtensionNamespace)));
                    }
                }
            }

            // Adding input parameters
            if (evaluatedParameterList.Count > 0)
            {
                foreach (KeyValuePair<string, XElement> parameter in evaluatedParameterList)
                {
                    if (addDetailedComments)
                    {
                        inputRoot.Add(new XComment(string.Format(" Input Parameter, XPath /in:inputs/in:param[@name='{0}'] ", parameter.Key)));
                    }
                    inputRoot.Add(parameter.Value);
                }
            }

            if (namedFunctions.Count > 0)
            {
                var functionCallResults = new object[namedFunctions.Count];
                var functionCallExecutionTimes = new long[namedFunctions.Count];

                for(int i=0; i<namedFunctions.Count; i++)
                {
                    FunctionContextContainer functionContextContainer = new FunctionContextContainer(inputParameters);

                    var namedFunctionCall = namedFunctions[i];
                    object result = null;
                    Stopwatch executionStopwatch = Stopwatch.StartNew();
                    try
                    {
                        result = GetFunctionCallResult(functionContextContainer, namedFunctionCall, addDetailedComments);

                        executionStopwatch.Stop();
                    }
                    catch (Exception ex)
                    {
                        throw new InvalidOperationException(string.Format("Failed to execute function with local name '{0}'", namedFunctionCall.Name), ex);
                    }

                    functionCallResults[i] = result;
                    functionCallExecutionTimes[i] = executionStopwatch.ElapsedMilliseconds;
                };

                for (int i=0; i<namedFunctions.Count; i++)
                {
                    object result = functionCallResults[i];

                    if (result is IXsltExtensionDefinition)
                    {
                        IXsltExtensionDefinition extensionDefinition = (IXsltExtensionDefinition)result;
                        transformationInputs.ExtensionDefinitions = transformationInputs.ExtensionDefinitions ?? new List<IXsltExtensionDefinition>();
                        transformationInputs.ExtensionDefinitions.Add(extensionDefinition);

                        if (addDetailedComments)
                        {
                            string name = namedFunctions[i].Name;
                            inputRoot.Add(new XComment(string.Format(" Function call result '{0}' has been registered as an Xslt Entension Object. ", name, extensionDefinition.ExtensionNamespace)));
                            inputRoot.Add(new XComment(string.Format(" Extension methods can be called using the namespace '{1}'. ", name, extensionDefinition.ExtensionNamespace)));
                            inputRoot.Add(new XComment(" The following methods exist: "));
                            foreach (MethodInfo mi in extensionDefinition.EntensionObjectAsObject.GetType().GetMethods().Where(m => m.DeclaringType != typeof(object)))
                            {
                                string paramsInfo = string.Join(", ", mi.GetParameters().Select(p => string.Format("{0} {1}", p.ParameterType.Name, p.Name)).ToArray());
                                string returnTypeName = (mi.ReturnType != null ? mi.ReturnType.Name : "void");
                                inputRoot.Add(new XComment(string.Format(" {0} ns:{1}({2}) ", returnTypeName, mi.Name, paramsInfo)));
                            }
                        }
                    }
                    else
                    {
                        Verify.That(result is XElement, "Function call result had to be selialized as XElement");

                        if (addDetailedComments)
                        {
                            string xpathAppend = FindElementXPathAppend(result);

                            inputRoot.Add(new XComment(string.Format(" Function Call Result ({0} ms), XPath /in:inputs/in:result[@name='{1}']{2} ", functionCallExecutionTimes[i], namedFunctions[i].Name, xpathAppend)));
                        }

                        inputRoot.Add(result as XElement);
                    }
                }
            }

            return transformationInputs;
        }