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