System.Xml.Xsl.Runtime.XmlQueryRuntime.ChangeTypeXsltResult C# (CSharp) Method

ChangeTypeXsltResult() private method

Convert from the Clr type of "value" to the default Clr type that ILGen uses to represent the xml type, using the conversion rules of the xml type.
private ChangeTypeXsltResult ( XmlQueryType xmlType, object value ) : object
xmlType XmlQueryType
value object
return object
        internal object ChangeTypeXsltResult(XmlQueryType xmlType, object value) {
            if (value == null)
                throw new XslTransformException(Res.Xslt_ItemNull, string.Empty);

            switch (xmlType.TypeCode) {
                case XmlTypeCode.String:
                    if (value.GetType() == XsltConvert.DateTimeType)
                        value = XsltConvert.ToString((DateTime) value);
                    break;

                case XmlTypeCode.Double:
                    if (value.GetType() != XsltConvert.DoubleType)
                        value = ((IConvertible) value).ToDouble(null);

                    break;

                case XmlTypeCode.Node:
                    if (!xmlType.IsSingleton) {
                        XPathArrayIterator iter = value as XPathArrayIterator;

                        // Special-case XPathArrayIterator in order to avoid copies
                        if (iter != null && iter.AsList is XmlQueryNodeSequence) {
                            value = iter.AsList as XmlQueryNodeSequence;
                        }
                        else {
                            // Iterate over list and ensure it only contains nodes
                            XmlQueryNodeSequence seq = new XmlQueryNodeSequence();
                            IList list = value as IList;

                            if (list != null) {
                                for (int i = 0; i < list.Count; i++)
                                    seq.Add(EnsureNavigator(list[i]));
                            }
                            else {
                                foreach (object o in (IEnumerable) value)
                                    seq.Add(EnsureNavigator(o));
                            }

                            value = seq;
                        }

                        // Always sort node-set by document order
                        value = ((XmlQueryNodeSequence) value).DocOrderDistinct(this.docOrderCmp);
                    }
                    break;

                case XmlTypeCode.Item: {
                    Type sourceType = value.GetType();
                    IXPathNavigable navigable;

                    // If static type is item, then infer type based on dynamic value
                    switch (XsltConvert.InferXsltType(sourceType).TypeCode) {
                        case XmlTypeCode.Boolean:
                            value = new XmlQueryItemSequence(new XmlAtomicValue(XmlSchemaType.GetBuiltInSimpleType(XmlTypeCode.Boolean), value));
                            break;

                        case XmlTypeCode.Double:
                            value = new XmlQueryItemSequence(new XmlAtomicValue(XmlSchemaType.GetBuiltInSimpleType(XmlTypeCode.Double), ((IConvertible) value).ToDouble(null)));
                            break;

                        case XmlTypeCode.String:
                            if (sourceType == XsltConvert.DateTimeType)
                                value = new XmlQueryItemSequence(new XmlAtomicValue(XmlSchemaType.GetBuiltInSimpleType(XmlTypeCode.String), XsltConvert.ToString((DateTime) value)));
                            else
                                value = new XmlQueryItemSequence(new XmlAtomicValue(XmlSchemaType.GetBuiltInSimpleType(XmlTypeCode.String), value));
                            break;

                        case XmlTypeCode.Node:
                            // Support XPathNavigator[]
                            value = ChangeTypeXsltResult(XmlQueryTypeFactory.NodeS, value);
                            break;

                        case XmlTypeCode.Item:
                            // Support XPathNodeIterator
                            if (value is XPathNodeIterator) {
                                value = ChangeTypeXsltResult(XmlQueryTypeFactory.NodeS, value);
                                break;
                            }

                            // Support IXPathNavigable and XPathNavigator
                            navigable = value as IXPathNavigable;
                            if (navigable != null) {
                                if (value is XPathNavigator)
                                    value = new XmlQueryNodeSequence((XPathNavigator) value);
                                else
                                    value = new XmlQueryNodeSequence(navigable.CreateNavigator());
                                break;
                            }

                            throw new XslTransformException(Res.Xslt_UnsupportedClrType, sourceType.Name);
                    }
                    break;
                }
            }

            Debug.Assert(XmlILTypeHelper.GetStorageType(xmlType).IsAssignableFrom(value.GetType()), "Xml type " + xmlType + " is not represented in ILGen as " + value.GetType().Name);
            return value;
        }

Same methods

XmlQueryRuntime::ChangeTypeXsltResult ( int indexType, object value ) : object

Usage Example

Exemplo n.º 1
0
        /// <summary>
        /// Get a late-bound extension object from the external argument list.  Bind to a method on the object and invoke it,
        /// passing "args" as arguments.
        /// </summary>
        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] = _runtime.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));
        }