Ejemplo n.º 1
0
        /// <summary>
        /// If "seq" is non-null, then clear it and reuse it.  Otherwise, create a new XmlQueryNodeSequence.
        /// Add "nav" to the sequence.
        /// </summary>
        public static XmlQueryNodeSequence CreateOrReuse(XmlQueryNodeSequence seq, XPathNavigator navigator)
        {
            if (seq != null)
            {
                seq.Clear();
                seq.Add(navigator);
                return(seq);
            }

            return(new XmlQueryNodeSequence(navigator));
        }
        /// <summary>
        /// Return the fully merged sequence.
        /// </summary>
        public IList <XPathNavigator> MergeSequences()
        {
            XmlQueryNodeSequence newSequence;

            // Zero sequences to merge
            if (this.firstSequence == null)
            {
                return(XmlQueryNodeSequence.Empty);
            }

            // One sequence to merge
            if (this.sequencesToMerge == null || this.sequencesToMerge.Count <= 1)
            {
                return(this.firstSequence);
            }

            // Two or more sequences to merge
            newSequence = new XmlQueryNodeSequence(this.nodeCount);

            while (this.sequencesToMerge.Count != 1)
            {
                // Save last item in list in temp variable, and remove it from list
                IEnumerator <XPathNavigator> sequence = this.sequencesToMerge[this.sequencesToMerge.Count - 1];
                this.sequencesToMerge.RemoveAt(this.sequencesToMerge.Count - 1);

                // Add current node to merged sequence
                newSequence.Add(sequence.Current);

                // Now move to the next node, and re-insert it into the list in reverse document order
                MoveAndInsertSequence(sequence);
            }

            // Add nodes in remaining sequence to end of list
            Debug.Assert(this.sequencesToMerge.Count == 1, "While loop should terminate when count == 1");
            do
            {
                newSequence.Add(this.sequencesToMerge[0].Current);
            }while (this.sequencesToMerge[0].MoveNext());

            return(newSequence);
        }
Ejemplo n.º 3
0
        public static IList <XPathNavigator> ItemsToNavigators(IList <XPathItem> listItems)
        {
            // Check to see if the navigator cache implements IList<XPathNavigator>
            IList <XPathNavigator> listNavs = listItems as IList <XPathNavigator>;

            if (listNavs != null)
            {
                return(listNavs);
            }

            // Create XmlQueryNodeSequence, which does implement IList<XPathNavigator>
            XmlQueryNodeSequence seq = new XmlQueryNodeSequence(listItems.Count);

            for (int i = 0; i < listItems.Count; i++)
            {
                seq.Add((XPathNavigator)listItems[i]);
            }

            return(seq);
        }
Ejemplo n.º 4
0
        /// <summary>
        /// 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.
        /// </summary>
        internal object ChangeTypeXsltResult(XmlQueryType xmlType, object value)
        {
            if (value == null)
            {
                throw new XslTransformException(SR.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(_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(SR.Xslt_UnsupportedClrType, sourceType.Name);
                }
                break;
            }
            }

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