KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > xalan > lib > ExsltSets


1 /*
2  * Copyright 1999-2004 The Apache Software Foundation.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */

16 /*
17  * $Id: ExsltSets.java,v 1.10 2004/02/11 17:56:36 minchau Exp $
18  */

19 package org.apache.xalan.lib;
20
21 import java.util.Hashtable JavaDoc;
22
23 import org.apache.xml.utils.DOMHelper;
24 import org.apache.xpath.NodeSet;
25 import org.w3c.dom.Node JavaDoc;
26 import org.w3c.dom.NodeList JavaDoc;
27
28 /**
29  * This class contains EXSLT set extension functions.
30  * It is accessed by specifying a namespace URI as follows:
31  * <pre>
32  * xmlns:set="http://exslt.org/sets"
33  * </pre>
34  *
35  * The documentation for each function has been copied from the relevant
36  * EXSLT Implementer page.
37  *
38  * @see <a HREF="http://www.exslt.org/">EXSLT</a>
39  * @xsl.usage general
40  */

41 public class ExsltSets extends ExsltBase
42 {
43   /**
44    * The set:leading function returns the nodes in the node set passed as the first argument that
45    * precede, in document order, the first node in the node set passed as the second argument. If
46    * the first node in the second node set is not contained in the first node set, then an empty
47    * node set is returned. If the second node set is empty, then the first node set is returned.
48    *
49    * @param nl1 NodeList for first node-set.
50    * @param nl2 NodeList for second node-set.
51    * @return a NodeList containing the nodes in nl1 that precede in document order the first
52    * node in nl2; an empty node-set if the first node in nl2 is not in nl1; all of nl1 if nl2
53    * is empty.
54    *
55    * @see <a HREF="http://www.exslt.org/">EXSLT</a>
56    */

57   public static NodeList JavaDoc leading (NodeList JavaDoc nl1, NodeList JavaDoc nl2)
58   {
59     if (nl2.getLength() == 0)
60       return nl1;
61       
62     NodeSet ns1 = new NodeSet(nl1);
63     NodeSet leadNodes = new NodeSet();
64     Node JavaDoc endNode = nl2.item(0);
65     if (!ns1.contains(endNode))
66       return leadNodes; // empty NodeSet
67

68     for (int i = 0; i < nl1.getLength(); i++)
69     {
70       Node JavaDoc testNode = nl1.item(i);
71       if (DOMHelper.isNodeAfter(testNode, endNode)
72           && !DOMHelper.isNodeTheSame(testNode, endNode))
73         leadNodes.addElement(testNode);
74     }
75     return leadNodes;
76   }
77   
78   /**
79    * The set:trailing function returns the nodes in the node set passed as the first argument that
80    * follow, in document order, the first node in the node set passed as the second argument. If
81    * the first node in the second node set is not contained in the first node set, then an empty
82    * node set is returned. If the second node set is empty, then the first node set is returned.
83    *
84    * @param nl1 NodeList for first node-set.
85    * @param nl2 NodeList for second node-set.
86    * @return a NodeList containing the nodes in nl1 that follow in document order the first
87    * node in nl2; an empty node-set if the first node in nl2 is not in nl1; all of nl1 if nl2
88    * is empty.
89    *
90    * @see <a HREF="http://www.exslt.org/">EXSLT</a>
91    */

92   public static NodeList JavaDoc trailing (NodeList JavaDoc nl1, NodeList JavaDoc nl2)
93   {
94     if (nl2.getLength() == 0)
95       return nl1;
96       
97     NodeSet ns1 = new NodeSet(nl1);
98     NodeSet trailNodes = new NodeSet();
99     Node JavaDoc startNode = nl2.item(0);
100     if (!ns1.contains(startNode))
101       return trailNodes; // empty NodeSet
102

103     for (int i = 0; i < nl1.getLength(); i++)
104     {
105       Node JavaDoc testNode = nl1.item(i);
106       if (DOMHelper.isNodeAfter(startNode, testNode)
107           && !DOMHelper.isNodeTheSame(startNode, testNode))
108         trailNodes.addElement(testNode);
109     }
110     return trailNodes;
111   }
112   
113   /**
114    * The set:intersection function returns a node set comprising the nodes that are within
115    * both the node sets passed as arguments to it.
116    *
117    * @param nl1 NodeList for first node-set.
118    * @param nl2 NodeList for second node-set.
119    * @return a NodeList containing the nodes in nl1 that are also
120    * in nl2.
121    *
122    * @see <a HREF="http://www.exslt.org/">EXSLT</a>
123    */

124   public static NodeList JavaDoc intersection(NodeList JavaDoc nl1, NodeList JavaDoc nl2)
125   {
126     NodeSet ns1 = new NodeSet(nl1);
127     NodeSet ns2 = new NodeSet(nl2);
128     NodeSet inter = new NodeSet();
129
130     inter.setShouldCacheNodes(true);
131
132     for (int i = 0; i < ns1.getLength(); i++)
133     {
134       Node JavaDoc n = ns1.elementAt(i);
135
136       if (ns2.contains(n))
137         inter.addElement(n);
138     }
139
140     return inter;
141   }
142   
143   /**
144    * The set:difference function returns the difference between two node sets - those nodes that
145    * are in the node set passed as the first argument that are not in the node set passed as the
146    * second argument.
147    *
148    * @param nl1 NodeList for first node-set.
149    * @param nl2 NodeList for second node-set.
150    * @return a NodeList containing the nodes in nl1 that are not in nl2.
151    *
152    * @see <a HREF="http://www.exslt.org/">EXSLT</a>
153    */

154   public static NodeList JavaDoc difference(NodeList JavaDoc nl1, NodeList JavaDoc nl2)
155   {
156     NodeSet ns1 = new NodeSet(nl1);
157     NodeSet ns2 = new NodeSet(nl2);
158
159     NodeSet diff = new NodeSet();
160
161     diff.setShouldCacheNodes(true);
162
163     for (int i = 0; i < ns1.getLength(); i++)
164     {
165       Node JavaDoc n = ns1.elementAt(i);
166
167       if (!ns2.contains(n))
168         diff.addElement(n);
169     }
170
171     return diff;
172   }
173   
174   /**
175    * The set:distinct function returns a subset of the nodes contained in the node-set NS passed
176    * as the first argument. Specifically, it selects a node N if there is no node in NS that has
177    * the same string value as N, and that precedes N in document order.
178    *
179    * @param nl NodeList for the node-set.
180    * @return a NodeList with nodes from nl containing distinct string values.
181    * In other words, if more than one node in nl contains the same string value,
182    * only include the first such node found.
183    *
184    * @see <a HREF="http://www.exslt.org/">EXSLT</a>
185    */

186   public static NodeList JavaDoc distinct(NodeList JavaDoc nl)
187   {
188     NodeSet dist = new NodeSet();
189     dist.setShouldCacheNodes(true);
190
191     Hashtable JavaDoc stringTable = new Hashtable JavaDoc();
192     
193     for (int i = 0; i < nl.getLength(); i++)
194     {
195       Node JavaDoc currNode = nl.item(i);
196       String JavaDoc key = toString(currNode);
197       
198       if (key == null)
199         dist.addElement(currNode);
200       else if (!stringTable.containsKey(key))
201       {
202         stringTable.put(key, currNode);
203         dist.addElement(currNode);
204       }
205     }
206
207     return dist;
208   }
209   
210   /**
211    * The set:has-same-node function returns true if the node set passed as the first argument shares
212    * any nodes with the node set passed as the second argument. If there are no nodes that are in both
213    * node sets, then it returns false.
214    *
215    * The Xalan extensions MethodResolver converts 'has-same-node' to 'hasSameNode'.
216    *
217    * Note: Not to be confused with hasSameNodes in the Xalan namespace, which returns true if
218    * the two node sets contain the exactly the same nodes (perhaps in a different order),
219    * otherwise false.
220    *
221    * @see <a HREF="http://www.exslt.org/">EXSLT</a>
222    */

223   public static boolean hasSameNode(NodeList JavaDoc nl1, NodeList JavaDoc nl2)
224   {
225     
226     NodeSet ns1 = new NodeSet(nl1);
227     NodeSet ns2 = new NodeSet(nl2);
228
229     for (int i = 0; i < ns1.getLength(); i++)
230     {
231       if (ns2.contains(ns1.elementAt(i)))
232         return true;
233     }
234     return false;
235   }
236   
237 }
238
Popular Tags