1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50 package org.jaxen.xom;
51
52
53 import nu.xom.Attribute;
54 import nu.xom.Comment;
55 import nu.xom.Document;
56 import nu.xom.Element;
57 import nu.xom.ProcessingInstruction;
58 import nu.xom.Text;
59 import nu.xom.Node;
60 import nu.xom.Builder;
61 import nu.xom.NodeFactory;
62 import nu.xom.ParentNode;
63
64 import org.jaxen.XPath;
65 import org.jaxen.UnsupportedAxisException;
66 import org.jaxen.FunctionCallException;
67 import org.jaxen.BaseXPath;
68 import org.jaxen.JaxenConstants;
69 import org.jaxen.util.SingleObjectIterator;
70
71 import org.jaxen.saxpath.SAXPathException;
72
73 import java.util.Iterator;
74 import java.util.HashMap;
75 import java.util.Map;
76
77
78
79
80
81
82
83
84
85
86
87
88 public class DocumentNavigator extends org.jaxen.DefaultNavigator
89 {
90
91
92
93 private static final long serialVersionUID = 3159311338575942877L;
94
95 public boolean isAttribute(Object o) {
96 return o instanceof Attribute;
97 }
98
99 public boolean isComment(Object o) {
100 return o instanceof Comment;
101 }
102
103 public boolean isDocument(Object o) {
104 return o instanceof Document;
105 }
106
107 public boolean isElement(Object o) {
108 return o instanceof Element;
109 }
110
111 public boolean isNamespace(Object o) {
112 return o instanceof XPathNamespace;
113 }
114
115 public boolean isProcessingInstruction(Object o) {
116 return o instanceof ProcessingInstruction;
117 }
118
119 public boolean isText(Object o) {
120 return o instanceof Text;
121 }
122
123
124
125 public String getAttributeName(Object o) {
126 return (isAttribute(o) ? ((Attribute)o).getLocalName() : null);
127 }
128
129 public String getAttributeNamespaceUri(Object o) {
130 return (isAttribute(o) ? ((Attribute)o).getNamespaceURI() : null);
131 }
132
133 public String getAttributeQName(Object o) {
134 return (isAttribute(o) ? ((Attribute)o).getQualifiedName() : null);
135 }
136
137 public String getAttributeStringValue(Object o) {
138 return (isAttribute(o) ? ((Attribute)o).getValue() : null);
139 }
140
141
142
143 public String getCommentStringValue(Object o) {
144 return (isComment(o) ? ((Comment)o).getValue() : null);
145 }
146
147 public String getElementName(Object o) {
148 return (isElement(o) ? ((Element)o).getLocalName() : null);
149 }
150
151 public String getElementNamespaceUri(Object o) {
152 return (isElement(o) ? ((Element)o).getNamespaceURI() : null);
153 }
154
155 public String getElementQName(Object o) {
156 return (isElement(o) ? ((Element)o).getQualifiedName() : null);
157 }
158
159 public String getElementStringValue(Object o) {
160 return (o instanceof Node ? ((Node)o).getValue() : null);
161 }
162
163
164
165 public String getNamespacePrefix(Object o) {
166 if (isElement(o)) {
167 return ((Element)o).getNamespacePrefix();
168 } else if (isAttribute(o)) {
169 return ((Attribute)o).getNamespacePrefix();
170 } else if (o instanceof XPathNamespace) {
171 return ((XPathNamespace)o).getNamespacePrefix();
172 }
173 return null;
174 }
175
176 public String getNamespaceStringValue(Object o) {
177 if (isElement(o)) {
178 return ((Element)o).getNamespaceURI();
179 } else if (isAttribute(o)) {
180 return ((Attribute)o).getNamespaceURI();
181 } else if (o instanceof XPathNamespace) {
182 return ((XPathNamespace)o).getNamespaceURI();
183 }
184 return null;
185 }
186
187
188
189 public String getTextStringValue(Object o) {
190 return (o instanceof Text ? ((Text)o).getValue() : null);
191 }
192
193
194
195 public Object getDocument(String s) throws FunctionCallException {
196 try {
197 return new Builder(new NodeFactory()).build(s);
198 } catch (Exception pe) {
199 throw new FunctionCallException(pe);
200 }
201 }
202
203 public Object getDocumentNode(Object o) {
204 ParentNode parent = null;
205 if (o instanceof ParentNode) {
206 parent = (ParentNode)o;
207 } else if (o instanceof Node) {
208 parent = ((Node)o).getParent();
209 }
210 return parent.getDocument();
211 }
212
213
214
215 private abstract static class IndexIterator implements Iterator {
216 private Object o = null;
217 private int pos = 0, end = -1;
218 public IndexIterator(Object o, int pos, int end) {
219 this.o = o;
220 this.pos = pos;
221 this.end = end;
222 }
223 public boolean hasNext() {
224 return pos < end;
225 }
226 public abstract Object get(Object o, int i);
227
228 public Object next() {
229 return get(o, pos++);
230 }
231
232 public void remove() {
233 throw new UnsupportedOperationException();
234 }
235 }
236
237
238
239 public Iterator getAttributeAxisIterator(Object o) {
240 if (isElement(o)) {
241 return new IndexIterator(o, 0, ((Element)o).getAttributeCount()) {
242 public Object get(Object o, int i) {
243 return ((Element)o).getAttribute(i);
244 }
245 };
246 }
247 return JaxenConstants.EMPTY_ITERATOR;
248 }
249
250 public Iterator getChildAxisIterator(Object o) {
251 if (isElement(o) || (o instanceof Document)) {
252 return new IndexIterator(o, 0, ((ParentNode)o).getChildCount()) {
253 public Object get(Object o, int i) {
254 return ((ParentNode)o).getChild(i);
255 }
256 };
257 }
258 return JaxenConstants.EMPTY_ITERATOR;
259 }
260
261
262
263 public Iterator getParentAxisIterator(Object o) {
264 Object parent = null;
265 if (o instanceof Node) {
266 parent = ((Node)o).getParent();
267 } else if (isNamespace(o)) {
268 parent = ((XPathNamespace)o).getElement();
269 }
270 return (parent != null ? new SingleObjectIterator(parent) : null);
271 }
272
273 public Object getParentNode(Object o) {
274 return (o instanceof Node ? ((Node)o).getParent() : null);
275 }
276
277
278
279 public Iterator getPrecedingAxisIterator(Object o) throws UnsupportedAxisException {
280 return super.getPrecedingAxisIterator(o);
281 }
282
283 public Iterator getPrecedingSiblingAxisIterator(Object o) throws UnsupportedAxisException {
284 return super.getPrecedingSiblingAxisIterator(o);
285 }
286
287
288
289 public String getProcessingInstructionData(Object o) {
290 return (o instanceof ProcessingInstruction ? ((ProcessingInstruction)o).getValue() : null);
291 }
292
293 public String getProcessingInstructionTarget(Object o) {
294 return (o instanceof ProcessingInstruction ? ((ProcessingInstruction)o).getTarget() : null);
295 }
296
297
298
299 public String translateNamespacePrefixToUri(String s, Object o) {
300 Element element = null;
301 if (o instanceof Element) {
302 element = (Element) o;
303 } else if (o instanceof ParentNode) {
304 }
305 else if (o instanceof Node) {
306 element = (Element)((Node)o).getParent();
307 }
308 else if (o instanceof XPathNamespace)
309 {
310 element = ((XPathNamespace)o).getElement();
311 }
312 if (element != null) {
313 return element.getNamespaceURI(s);
314 }
315 return null;
316 }
317
318
319
320 public XPath parseXPath(String s) throws SAXPathException {
321 return new BaseXPath(s, this);
322 }
323
324
325
326
327
328
329
330
331 private static class XPathNamespace
332 {
333 private Element element;
334
335 private String uri, prefix;
336
337 public XPathNamespace(Element elt, String uri, String prefix)
338 {
339 element = elt;
340 this.uri = uri;
341 this.prefix = prefix;
342 }
343
344
345
346
347
348 public Element getElement()
349 {
350 return element;
351 }
352
353 public String getNamespaceURI()
354 {
355 return uri;
356 }
357
358 public String getNamespacePrefix()
359 {
360 return prefix;
361 }
362
363 public String toString()
364 {
365 return ( "[xmlns:" + prefix + "=\"" +
366 uri + "\", element=" +
367 element.getLocalName() + "]" );
368 }
369 }
370
371
372
373 private boolean addNamespaceForElement(Element elt, String uri, String prefix, Map map)
374 {
375 if (uri != null && uri.length() > 0 && (! map.containsKey(prefix))) {
376 map.put(prefix, new XPathNamespace(elt, uri, prefix));
377 return true;
378 }
379 return false;
380 }
381
382 public Iterator getNamespaceAxisIterator(Object o)
383 {
384 if (! isElement(o)) {
385 return JaxenConstants.EMPTY_ITERATOR;
386 }
387 Map nsMap = new HashMap();
388 Element elt = (Element)o;
389 ParentNode parent = elt;
390
391 while (parent instanceof Element) {
392 elt = (Element)parent;
393 String uri = elt.getNamespaceURI();
394 String prefix = elt.getNamespacePrefix();
395 addNamespaceForElement(elt, uri, prefix, nsMap);
396 int count = elt.getNamespaceDeclarationCount();
397 for (int i = 0; i < count; i++) {
398 prefix = elt.getNamespacePrefix(i);
399 uri = elt.getNamespaceURI(prefix);
400 addNamespaceForElement(elt, uri, prefix, nsMap);
401 }
402 parent = elt.getParent();
403 }
404 addNamespaceForElement(elt, "http://www.w3.org/XML/1998/namespace", "xml", nsMap);
405
406 return nsMap.values().iterator();
407 }
408 }