/// <summary> /// Implements the following function /// node-set trailing(node-set, node-set) /// </summary> /// <param name="nodeset1"></param> /// <param name="nodeset2"></param> /// <returns>returns the nodes in the node set passed as the /// first argument that follow, in document order, the first node /// in the node set passed as the second argument</returns> public XPathNodeIterator trailing(XPathNodeIterator nodeset1, XPathNodeIterator nodeset2) { XPathNavigator leader = null; if (nodeset2.MoveNext()) { leader = nodeset2.Current; } else { return(nodeset1); } ExsltNodeList nodelist1 = new ExsltNodeList(); while (nodeset1.MoveNext()) { if (nodeset1.Current.ComparePosition(leader) == XmlNodeOrder.After) { nodelist1.Add(nodeset1.Current.Clone()); } } return(ExsltCommon.ExsltNodeListToXPathNodeIterator(nodelist1)); }
/// <summary> /// Implements an optimized algorithm for the following function /// node-set difference(node-set, node-set) /// Uses document identification and binary search, /// based on the fact that a node-set is always in document order. /// </summary> /// <param name="nodeset1">An input nodeset</param> /// <param name="nodeset2">Another input nodeset</param> /// <returns>The those nodes that are in the node set /// passed as the first argument that are not in the node set /// passed as the second argument.</returns> /// <author>Dimitre Novatchev</author> private XPathNodeIterator difference2(XPathNodeIterator nodeset1, XPathNodeIterator nodeset2) { ArrayList arDocs = new ArrayList(); ArrayList arNodes2 = new ArrayList(nodeset2.Count); while (nodeset2.MoveNext()) { arNodes2.Add(nodeset2.Current.Clone()); } auxEXSLT.findDocs(arNodes2, arDocs); ExsltNodeList enlResult = new ExsltNodeList(); while (nodeset1.MoveNext()) { XPathNavigator currNode = nodeset1.Current; if (!auxEXSLT.findNode(arNodes2, arDocs, currNode)) { enlResult.Add(currNode.Clone()); } } return(ExsltCommon.ExsltNodeListToXPathNodeIterator(enlResult)); }
/// <summary> /// Implements the following function /// node-set distinct(node-set) /// </summary> /// <param name="nodeset">The input nodeset</param> /// <returns>Returns the nodes in the nodeset whose string value is /// distinct</returns> public XPathNodeIterator distinct(XPathNodeIterator nodeset) { if (nodeset.Count > 15) { return(distinct2(nodeset)); } //else ExsltNodeList nodelist = new ExsltNodeList(); while (nodeset.MoveNext()) { if (!nodelist.ContainsValue(nodeset.Current.Value)) { nodelist.Add(nodeset.Current.Clone()); } } return(ExsltCommon.ExsltNodeListToXPathNodeIterator(nodelist)); }
/// <summary> /// Implements the following function /// node-set distinct2(node-set) /// /// This implements an optimized algorithm /// using a Hashtable /// /// </summary> /// <param name="nodeset">The input nodeset</param> /// <returns>Returns the nodes in the nodeset whose string value is /// distinct</returns> /// <author>Dimitre Novatchev</author> private XPathNodeIterator distinct2(XPathNodeIterator nodeset) { ExsltNodeList nodelist = new ExsltNodeList(); Hashtable ht = new Hashtable(nodeset.Count / 3); while (nodeset.MoveNext()) { string strVal = nodeset.Current.Value; if (!ht.ContainsKey(strVal)) { ht.Add(strVal, ""); nodelist.Add(nodeset.Current.Clone()); } } return(ExsltCommon.ExsltNodeListToXPathNodeIterator(nodelist)); }
/// <summary> /// Implements the following function /// node-set highest(node-set) /// </summary> /// <param name="iterator">The input nodeset</param> /// <returns>All the nodes that contain the max value in the nodeset</returns> public XPathNodeIterator highest(XPathNodeIterator iterator) { ExsltNodeList newList = new ExsltNodeList(); double max, t; if (iterator.Count == 0) { return(ExsltCommon.ExsltNodeListToXPathNodeIterator(newList)); } try{ iterator.MoveNext(); max = XmlConvert.ToDouble(iterator.Current.Value); newList.Add(iterator.Current.Clone()); while (iterator.MoveNext()) { t = XmlConvert.ToDouble(iterator.Current.Value); if (t > max) { max = t; newList.Clear(); newList.Add(iterator.Current.Clone()); } else if (t == max) { newList.Add(iterator.Current.Clone()); } } }catch (Exception) { //return empty node set newList.Clear(); return(ExsltCommon.ExsltNodeListToXPathNodeIterator(newList)); } return(ExsltCommon.ExsltNodeListToXPathNodeIterator(newList)); }
/// <summary> /// Implements the following function /// node-set intersection3(node-set, node-set) /// /// This is an optimisation of the initial implementation /// of intersection(). It uses a document identification /// and a binary search algorithm, based on the fact /// that a node-set is always in document order. /// </summary> /// <param name="nodeset1">The first node-set</param> /// <param name="nodeset2">The second node-set</param> /// <returns>The node-set, which is the intersection /// of nodeset1 and nodeset2 /// </returns> /// <author>Dimitre Novatchev</author> private XPathNodeIterator intersection3(XPathNodeIterator nodeset1, XPathNodeIterator nodeset2) { XPathNodeIterator it1 = (nodeset1.Count > nodeset2.Count) ? nodeset1 : nodeset2; XPathNodeIterator it2 = (nodeset1.Count > nodeset2.Count) ? nodeset2 : nodeset1; ArrayList arDocs = new ArrayList(); ArrayList arNodes1 = new ArrayList(it1.Count); while (it1.MoveNext()) { arNodes1.Add(it1.Current.Clone()); } auxEXSLT.findDocs(arNodes1, arDocs); ExsltNodeList enlResult = new ExsltNodeList(); while (it2.MoveNext()) { XPathNavigator currNode = it2.Current; if (auxEXSLT.findNode(arNodes1, arDocs, currNode)) { enlResult.Add(currNode.Clone()); } } return(ExsltCommon.ExsltNodeListToXPathNodeIterator(enlResult)); }
/// <summary> /// Implements the following function /// node-set intersection(node-set, node-set) /// </summary> /// <param name="nodeset1">The first node-set</param> /// <param name="nodeset2">The second node-set</param> /// <returns>The node-set, which is the intersection /// of nodeset1 and nodeset2 /// </returns> public XPathNodeIterator intersection(XPathNodeIterator nodeset1, XPathNodeIterator nodeset2) { if (nodeset1.Count >= 500 || nodeset2.Count >= 500) { return(intersection3(nodeset1, nodeset2)); } //else ExsltNodeList nodelist1 = new ExsltNodeList(nodeset1, true); ExsltNodeList nodelist2 = new ExsltNodeList(nodeset2); for (int i = 0; i < nodelist1.Count; i++) { XPathNavigator nav = nodelist1[i]; if (!nodelist2.Contains(nav)) { nodelist1.RemoveAt(i); i--; } } return(ExsltCommon.ExsltNodeListToXPathNodeIterator(nodelist1)); }
/// <summary> /// Implements the following function /// node-set difference(node-set, node-set) /// </summary> /// <param name="nodeset1">An input nodeset</param> /// <param name="nodeset2">Another input nodeset</param> /// <returns>The those nodes that are in the node set /// passed as the first argument that are not in the node set /// passed as the second argument.</returns> public XPathNodeIterator difference(XPathNodeIterator nodeset1, XPathNodeIterator nodeset2) { if (nodeset2.Count > 166) { return(difference2(nodeset1, nodeset2)); } //else ExsltNodeList nodelist1 = new ExsltNodeList(nodeset1, true); ExsltNodeList nodelist2 = new ExsltNodeList(nodeset2); for (int i = 0; i < nodelist1.Count; i++) { XPathNavigator nav = nodelist1[i]; if (nodelist2.Contains(nav)) { nodelist1.RemoveAt(i); i--; } } return(ExsltCommon.ExsltNodeListToXPathNodeIterator(nodelist1)); }