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); }
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; }