001: package net.sf.saxon.exslt;
002:
003: import net.sf.saxon.expr.*;
004: import net.sf.saxon.om.Item;
005: import net.sf.saxon.om.NodeInfo;
006: import net.sf.saxon.om.SequenceIterator;
007: import net.sf.saxon.sort.GlobalOrderComparer;
008: import net.sf.saxon.trans.DynamicError;
009: import net.sf.saxon.trans.XPathException;
010: import net.sf.saxon.value.SingletonNode;
011:
012: /**
013: * This class implements extension functions in the
014: * http://exslt.org/sets namespace. <p>
015: */
016:
017: public abstract class Sets {
018:
019: private Sets() {
020: }
021:
022: /**
023: * Return the intersection of two node-sets
024: * @param p1 The first node-set
025: * @param p2 The second node-set
026: * @return A node-set containing all nodes that are in both p1 and p2
027: */
028:
029: public static SequenceIterator intersection(SequenceIterator p1,
030: SequenceIterator p2) throws XPathException {
031: return new IntersectionEnumeration(p1, p2, GlobalOrderComparer
032: .getInstance());
033: }
034:
035: /**
036: * Return the difference of two node-sets
037: * @param p1 The first node-set
038: * @param p2 The second node-set
039: * @return A node-set containing all nodes that are in p1 and not in p2
040: */
041:
042: public static SequenceIterator difference(SequenceIterator p1,
043: SequenceIterator p2) throws XPathException {
044: return new DifferenceEnumeration(p1, p2, GlobalOrderComparer
045: .getInstance());
046: }
047:
048: /**
049: * Determine whether two node-sets contain at least one node in common
050: * @param p1 The first node-set
051: * @param p2 The second node-set
052: * @return true if p1 and p2 contain at least one node in common (i.e. if the intersection
053: * is not empty)
054: */
055:
056: public static boolean hasSameNode(SequenceIterator p1,
057: SequenceIterator p2) throws XPathException {
058: SequenceIterator intersection = new IntersectionEnumeration(p1,
059: p2, GlobalOrderComparer.getInstance());
060: return intersection.next() != null;
061: }
062:
063: /**
064: * Find all the nodes in ns1 that are before the first node in ns2.
065: * Return empty set if ns2 is empty,
066: */
067:
068: public static SequenceIterator leading(XPathContext context,
069: SequenceIterator ns1, SequenceIterator ns2)
070: throws XPathException {
071:
072: NodeInfo first = null;
073:
074: // Find the first node in ns2 (in document order)
075:
076: GlobalOrderComparer comparer = GlobalOrderComparer
077: .getInstance();
078: while (true) {
079: Item item = ns2.next();
080: if (item == null) {
081: if (first == null) {
082: return ns1;
083: }
084: break;
085: }
086: if (item instanceof NodeInfo) {
087: NodeInfo node = (NodeInfo) item;
088: if (first == null) {
089: first = node;
090: } else {
091: if (comparer.compare(node, first) < 0) {
092: first = node;
093: }
094: }
095: } else {
096: DynamicError e = new DynamicError(
097: "Operand of leading() contains an item that is not a node");
098: e.setXPathContext(context);
099: throw e;
100: }
101: }
102:
103: // Filter ns1 to select nodes that come before this one
104:
105: Expression filter = new IdentityComparison(
106: new ContextItemExpression(), Token.PRECEDES,
107: new SingletonNode(first));
108:
109: return new FilterIterator(ns1, filter, context);
110:
111: }
112:
113: /**
114: * Find all the nodes in ns1 that are after the first node in ns2.
115: * Return empty set if ns2 is empty,
116: */
117:
118: public static SequenceIterator trailing(XPathContext c,
119: SequenceIterator ns1, SequenceIterator ns2)
120: throws XPathException {
121:
122: return net.sf.saxon.functions.Extensions.after(c, ns1, ns2);
123: }
124:
125: }
126:
127: //
128: // The contents of this file are subject to the Mozilla Public License Version 1.0 (the "License");
129: // you may not use this file except in compliance with the License. You may obtain a copy of the
130: // License at http://www.mozilla.org/MPL/
131: //
132: // Software distributed under the License is distributed on an "AS IS" basis,
133: // WITHOUT WARRANTY OF ANY KIND, either express or implied.
134: // See the License for the specific language governing rights and limitations under the License.
135: //
136: // The Original Code is: all this file.
137: //
138: // The Initial Developer of the Original Code is Michael H. Kay.
139: //
140: // Portions created by (your name) are Copyright (C) (your legal entity). All Rights Reserved.
141: //
142: // Contributor(s): none.
143: //
|