System.Xml.Xsl.Runtime.XmlExtensionFunction.Invoke C# (CSharp) Method

Invoke() public method

Convert the incoming arguments to an array of CLR objects, and then invoke the external function on the "extObj" object instance.
public Invoke ( object extObj, object args ) : object
extObj object
args object
return object
        public object Invoke(object extObj, object[] args) {
            Debug.Assert(this.meth != null, "Must call Bind() before calling Invoke.");
            Debug.Assert(args.Length == this.argClrTypes.Length, "Mismatched number of actual and formal arguments.");

            try {
                return this.meth.Invoke(extObj, this.flags, null, args, CultureInfo.InvariantCulture);
            }
            catch (TargetInvocationException e) {
                throw new XslTransformException(e.InnerException, Res.XmlIl_ExtensionError, this.name);
            }
            catch (Exception e) {
                if (!XmlException.IsCatchableException(e)) {
                    throw;
                }
                throw new XslTransformException(e, Res.XmlIl_ExtensionError, this.name);
            }
        }

Usage Example

Ejemplo n.º 1
0
        public IList <XPathItem> InvokeXsltLateBoundFunction(string name, string namespaceUri, IList <XPathItem>[] args)
        {
            object instance;

            object[]     objActualArgs;
            XmlQueryType xmlTypeFormalArg;
            Type         clrTypeFormalArg;
            object       objRet;

            // Get external object instance from argument list (throw if either the list or the instance doesn't exist)
            instance = (_argList != null) ? _argList.GetExtensionObject(namespaceUri) : null;
            if (instance == null)
            {
                throw new XslTransformException(SR.XmlIl_UnknownExtObj, namespaceUri);
            }

            // Bind to a method on the instance object
            if (_extFuncsLate == null)
            {
                _extFuncsLate = new XmlExtensionFunctionTable();
            }

            // Bind to the instance, looking for a matching method (throws if no matching method)
            XmlExtensionFunction extFunc = _extFuncsLate.Bind(name, namespaceUri, args.Length, instance.GetType(), XmlQueryRuntime.LateBoundFlags);

            // Create array which will contain the actual arguments
            objActualArgs = new object[args.Length];

            for (int i = 0; i < args.Length; i++)
            {
                // 1. Assume that the input value can only have one of the following 5 Xslt types:
                //      xs:double, xs:string, xs:boolean, node* (can be rtf)
                // 2. Convert each Rtf value to a NodeSet containing one node.  Now the value may only have one of the 4 Xslt types.
                // 3. Convert from one of the 4 Xslt internal types to the Xslt internal type which is closest to the formal
                //    argument's Xml type (inferred from the Clr type of the formal argument).

                xmlTypeFormalArg = extFunc.GetXmlArgumentType(i);
                switch (xmlTypeFormalArg.TypeCode)
                {
                case XmlTypeCode.Boolean: objActualArgs[i] = XsltConvert.ToBoolean(args[i]); break;

                case XmlTypeCode.Double: objActualArgs[i] = XsltConvert.ToDouble(args[i]); break;

                case XmlTypeCode.String: objActualArgs[i] = XsltConvert.ToString(args[i]); break;

                case XmlTypeCode.Node:
                    if (xmlTypeFormalArg.IsSingleton)
                    {
                        objActualArgs[i] = XsltConvert.ToNode(args[i]);
                    }
                    else
                    {
                        objActualArgs[i] = XsltConvert.ToNodeSet(args[i]);
                    }
                    break;

                case XmlTypeCode.Item:
                    objActualArgs[i] = args[i];
                    break;

                default:
                    Debug.Fail($"This XmlTypeCode should never be inferred from a Clr type: {xmlTypeFormalArg.TypeCode}");
                    break;
                }

                // 4. Change the Clr representation to the Clr type of the formal argument
                clrTypeFormalArg = extFunc.GetClrArgumentType(i);
                if (xmlTypeFormalArg.TypeCode == XmlTypeCode.Item || !clrTypeFormalArg.IsAssignableFrom(objActualArgs[i].GetType()))
                {
                    objActualArgs[i] = XmlQueryRuntime.ChangeTypeXsltArgument(xmlTypeFormalArg, objActualArgs[i], clrTypeFormalArg);
                }
            }

            // 1. Invoke the late bound method
            objRet = extFunc.Invoke(instance, objActualArgs);

            // 2. Convert to IList<XPathItem>
            if (objRet == null && extFunc.ClrReturnType == XsltConvert.VoidType)
            {
                return(XmlQueryNodeSequence.Empty);
            }

            return((IList <XPathItem>)_runtime.ChangeTypeXsltResult(XmlQueryTypeFactory.ItemS, objRet));
        }