/// <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;
        }
Пример #2
0
        /// <summary>
        /// Lookup a sequence of nodes that are indexed by the specified key value.
        /// Return a non-null empty sequence, if there are no nodes associated with the key.
        /// </summary>
        public XmlQueryNodeSequence Lookup(string key) {
            XmlQueryNodeSequence seq;

            if (!this.table.TryGetValue(key, out seq))
                seq = new XmlQueryNodeSequence();

            return seq;
        }
Пример #3
0
        /// <summary>
        /// Lookup a sequence of nodes that are indexed by the specified key value.
        /// Return a non-null empty sequence, if there are no nodes associated with the key.
        /// </summary>
        public XmlQueryNodeSequence Lookup(string key) {
            XmlQueryNodeSequence seq = (XmlQueryNodeSequence) this.table[key];

            if (seq == null)
                seq = new XmlQueryNodeSequence();

            return seq;
        }
Пример #4
0
        /// <summary>
        /// Add a node indexed by the specified key value.
        /// </summary>
        public void Add(string key, XPathNavigator navigator) {
            XmlQueryNodeSequence seq;

            if (!this.table.TryGetValue(key, out seq)) {
                // Create a new sequence and add it to the index
                seq = new XmlQueryNodeSequence();
                seq.AddClone(navigator);
                this.table.Add(key, seq);
            }
            else {
                // The nodes are guaranteed to be added in document order with possible duplicates.
                // Add node to the existing sequence if it differs from the last one.
                Debug.Assert(navigator.ComparePosition(seq[seq.Count - 1]) >= 0, "Index nodes must be added in document order");
                if (!navigator.IsSamePosition(seq[seq.Count - 1])) {
                    seq.AddClone(navigator);
                }
            }
        }
Пример #5
0
        /// <summary>
        /// Add a node indexed by the specified key value.
        /// </summary>
        public void Add(string key, XPathNavigator navigator) {
            XmlQueryNodeSequence seq = (XmlQueryNodeSequence) this.table[key];

            if (seq == null) {
                // Create a new sequence and add it to the index
                seq = new XmlQueryNodeSequence();
                seq.AddClone(navigator);
                this.table.Add(key, seq);
            }
            else {
                // Add node to existing sequence; don't add if it already there
                for (int i = 0; i < seq.Count; i++) {
                    if (navigator.IsSamePosition(seq[i]))
                        return;
                }

                seq.AddClone(navigator);
            }
        }
        /// <summary>
        /// Get a comparer which guarantees a stable ordering among nodes, even those from different documents.
        /// </summary>
        public IList<XPathNavigator> DocOrderDistinct(IList<XPathNavigator> seq) {
            if (seq.Count <= 1)
                return seq;

            XmlQueryNodeSequence nodeSeq = (XmlQueryNodeSequence) seq;
            if (nodeSeq == null)
                nodeSeq = new XmlQueryNodeSequence(seq);

            return nodeSeq.DocOrderDistinct(this.docOrderCmp);
        }
        /// <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(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;
        }
        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;
        }
 public static XmlQueryNodeSequence CreateOrReuse(XmlQueryNodeSequence seq, System.Xml.XPath.XPathNavigator navigator)
 {
 }
 // Methods
 public static XmlQueryNodeSequence CreateOrReuse(XmlQueryNodeSequence seq)
 {
 }