|
1 |
| |
|
2 |
| |
|
3 |
| |
|
4 |
| |
|
5 |
| |
|
6 |
| |
|
7 |
| |
|
8 |
| |
|
9 |
| |
|
10 |
| |
|
11 |
| |
|
12 |
| |
|
13 |
| |
|
14 |
| |
|
15 |
| |
|
16 |
| |
|
17 |
| |
|
18 |
| |
|
19 |
| |
|
20 |
| |
|
21 |
| |
|
22 |
| package nu.xom; |
|
23 |
| |
|
24 |
| |
|
25 |
| |
|
26 |
| |
|
27 |
| |
|
28 |
| |
|
29 |
| |
|
30 |
| |
|
31 |
| |
|
32 |
| |
|
33 |
| |
|
34 |
| import org.jaxen.DefaultNavigator; |
|
35 |
| import org.jaxen.FunctionCallException; |
|
36 |
| import org.jaxen.JaxenConstants; |
|
37 |
| import org.jaxen.JaxenException; |
|
38 |
| import org.jaxen.NamedAccessNavigator; |
|
39 |
| import org.jaxen.UnsupportedAxisException; |
|
40 |
| import org.jaxen.XPath; |
|
41 |
| import org.jaxen.util.SingleObjectIterator; |
|
42 |
| |
|
43 |
| import java.util.Iterator; |
|
44 |
| import java.util.List; |
|
45 |
| import java.util.ArrayList; |
|
46 |
| import java.util.Map; |
|
47 |
| import java.util.NoSuchElementException; |
|
48 |
| |
|
49 |
| |
|
50 |
| class JaxenNavigator extends DefaultNavigator implements NamedAccessNavigator { |
|
51 |
| |
|
52 |
| |
|
53 |
| private static final long serialVersionUID = 7008740797833836742L; |
|
54 |
| |
|
55 |
| |
|
56 |
255
| public Iterator getSelfAxisIterator(Object contextNode) {
|
|
57 |
| |
|
58 |
255
| if (contextNode instanceof Text) {
|
|
59 |
| |
|
60 |
5
| Text node = (Text) contextNode;
|
|
61 |
5
| ArrayList temp = new ArrayList();
|
|
62 |
5
| ParentNode parent = node.getParent();
|
|
63 |
| |
|
64 |
5
| int index = parent.indexOf(node);
|
|
65 |
5
| int first = index;
|
|
66 |
5
| int last = index;
|
|
67 |
5
| while (first > 0 && parent.getChild(first-1).isText()) {
|
|
68 |
2
| first--;
|
|
69 |
| } |
|
70 |
5
| while (last < parent.getChildCount()-1 && parent.getChild(last+1).isText()) {
|
|
71 |
4
| last++;
|
|
72 |
| } |
|
73 |
5
| for (int i = first; i <= last; i++) {
|
|
74 |
11
| temp.add(parent.getChild(i));
|
|
75 |
| } |
|
76 |
5
| contextNode = temp;
|
|
77 |
| } |
|
78 |
255
| return new SingleObjectIterator(contextNode);
|
|
79 |
| |
|
80 |
| } |
|
81 |
| |
|
82 |
| |
|
83 |
44
| public Object getElementById(Object node, String id) {
|
|
84 |
| |
|
85 |
44
| Node original;
|
|
86 |
44
| if (node instanceof ArrayList) {
|
|
87 |
12
| original = (Node) ((List) node).get(0);
|
|
88 |
| } |
|
89 |
| else { |
|
90 |
32
| original = (Node) node;
|
|
91 |
| } |
|
92 |
44
| ParentNode parent;
|
|
93 |
44
| if (original.isElement() || original.isDocument()) {
|
|
94 |
11
| parent = (ParentNode) original;
|
|
95 |
| } |
|
96 |
| else { |
|
97 |
33
| parent = original.getParent();
|
|
98 |
| } |
|
99 |
| |
|
100 |
| |
|
101 |
44
| ParentNode high = parent;
|
|
102 |
44
| while (parent != null) {
|
|
103 |
136
| high = parent;
|
|
104 |
136
| parent = parent.getParent();
|
|
105 |
| } |
|
106 |
| |
|
107 |
| |
|
108 |
44
| Element root;
|
|
109 |
44
| if (high.isDocument()) {
|
|
110 |
39
| root = ((Document) high).getRootElement();
|
|
111 |
| } |
|
112 |
| else { |
|
113 |
5
| Node first = high.getChild(0);
|
|
114 |
5
| if (first.isElement()) {
|
|
115 |
3
| root = (Element) high.getChild(0);
|
|
116 |
| } |
|
117 |
| else { |
|
118 |
2
| return null;
|
|
119 |
| } |
|
120 |
| } |
|
121 |
| |
|
122 |
42
| return findByID(root, id);
|
|
123 |
| |
|
124 |
| } |
|
125 |
| |
|
126 |
| |
|
127 |
| |
|
128 |
163
| public static Element findByID(Element top, String id) {
|
|
129 |
| |
|
130 |
41
| if (hasID(top, id)) return top;
|
|
131 |
| else { |
|
132 |
122
| Elements children = top.getChildElements();
|
|
133 |
122
| for (int i = 0; i < children.size(); i++) {
|
|
134 |
121
| Element result = findByID(children.get(i), id);
|
|
135 |
115
| if (result != null) return result;
|
|
136 |
| } |
|
137 |
| } |
|
138 |
7
| return null;
|
|
139 |
| |
|
140 |
| } |
|
141 |
| |
|
142 |
| |
|
143 |
163
| private static boolean hasID(Element top, String id) {
|
|
144 |
| |
|
145 |
163
| int count = top.getAttributeCount();
|
|
146 |
163
| for (int i = 0; i < count; i++) {
|
|
147 |
79
| Attribute a = top.getAttribute(i);
|
|
148 |
79
| if (Attribute.Type.ID == a.getType()) {
|
|
149 |
| |
|
150 |
| |
|
151 |
| |
|
152 |
| |
|
153 |
41
| return a.getValue().trim().equals(id);
|
|
154 |
| } |
|
155 |
| } |
|
156 |
122
| return false;
|
|
157 |
| |
|
158 |
| } |
|
159 |
| |
|
160 |
| |
|
161 |
409
| public String getNamespacePrefix(Object o) {
|
|
162 |
409
| Namespace ns = (Namespace) o;
|
|
163 |
409
| return ns.getPrefix();
|
|
164 |
| } |
|
165 |
| |
|
166 |
| |
|
167 |
52
| public String getNamespaceStringValue(Object o) {
|
|
168 |
52
| Namespace ns = (Namespace) o;
|
|
169 |
52
| return ns.getValue();
|
|
170 |
| } |
|
171 |
| |
|
172 |
| |
|
173 |
289
| public Iterator getNamespaceAxisIterator(Object contextNode) {
|
|
174 |
| |
|
175 |
289
| try {
|
|
176 |
289
| Element element = (Element) contextNode;
|
|
177 |
| |
|
178 |
184
| Map bindings = element.getNamespacePrefixesInScope();
|
|
179 |
184
| Iterator iterator = bindings.entrySet().iterator();
|
|
180 |
184
| List result = new ArrayList(bindings.size()+1);
|
|
181 |
184
| result.add(new Namespace("xml",
|
|
182 |
| "http://www.w3.org/XML/1998/namespace", element)); |
|
183 |
| |
|
184 |
184
| while (iterator.hasNext()) {
|
|
185 |
365
| Map.Entry binding = (Map.Entry) iterator.next();
|
|
186 |
365
| String prefix = (String) binding.getKey();
|
|
187 |
365
| String uri = (String) binding.getValue();
|
|
188 |
365
| if (! "".equals(prefix) || ! "".equals(uri)) {
|
|
189 |
236
| Namespace ns = new Namespace(prefix, uri, element);
|
|
190 |
236
| result.add(ns);
|
|
191 |
| } |
|
192 |
| } |
|
193 |
184
| return result.iterator();
|
|
194 |
| } |
|
195 |
| catch (ClassCastException ex) { |
|
196 |
105
| return JaxenConstants.EMPTY_ITERATOR;
|
|
197 |
| } |
|
198 |
| |
|
199 |
| } |
|
200 |
| |
|
201 |
| |
|
202 |
86
| public Iterator getParentAxisIterator(Object contextNode) {
|
|
203 |
| |
|
204 |
86
| Node parent = (Node) getParentNode(contextNode);
|
|
205 |
2
| if (parent == null) return JaxenConstants.EMPTY_ITERATOR;
|
|
206 |
84
| else return new SingleObjectIterator(parent);
|
|
207 |
| |
|
208 |
| } |
|
209 |
| |
|
210 |
| |
|
211 |
410
| public Object getDocumentNode(Object o) {
|
|
212 |
| |
|
213 |
410
| Node node = (Node) o;
|
|
214 |
410
| return node.getRoot();
|
|
215 |
| |
|
216 |
| } |
|
217 |
| |
|
218 |
| |
|
219 |
0
| public Object getDocument(String url) throws FunctionCallException {
|
|
220 |
0
| throw new FunctionCallException("document() function not supported");
|
|
221 |
| } |
|
222 |
| |
|
223 |
4541
| public Iterator getAttributeAxisIterator(Object contextNode) {
|
|
224 |
| |
|
225 |
4541
| try {
|
|
226 |
4541
| Element element = (Element) contextNode;
|
|
227 |
4495
| return element.attributeIterator();
|
|
228 |
| } |
|
229 |
| catch (ClassCastException ex) { |
|
230 |
46
| return JaxenConstants.EMPTY_ITERATOR;
|
|
231 |
| } |
|
232 |
| |
|
233 |
| } |
|
234 |
| |
|
235 |
| |
|
236 |
164700
| public Iterator getChildAxisIterator(Object o) {
|
|
237 |
| |
|
238 |
164700
| if (o instanceof ParentNode) {
|
|
239 |
56369
| return new ChildIterator((ParentNode) o);
|
|
240 |
| } |
|
241 |
| else { |
|
242 |
108331
| return JaxenConstants.EMPTY_ITERATOR;
|
|
243 |
| } |
|
244 |
| |
|
245 |
| } |
|
246 |
| |
|
247 |
| |
|
248 |
2834
| public Iterator getFollowingSiblingAxisIterator(Object o) {
|
|
249 |
| |
|
250 |
2834
| Node start;
|
|
251 |
2834
| if (o instanceof ArrayList) {
|
|
252 |
108
| List list = (ArrayList) o;
|
|
253 |
108
| start = (Node) list.get(list.size()-1);
|
|
254 |
| } |
|
255 |
| else { |
|
256 |
2726
| start = (Node) o;
|
|
257 |
| } |
|
258 |
2834
| ParentNode parent = start.getParent();
|
|
259 |
1
| if (parent == null) return JaxenConstants.EMPTY_ITERATOR;
|
|
260 |
2833
| int startPos = parent.indexOf(start) + 1;
|
|
261 |
2833
| return new ChildIterator(parent, startPos);
|
|
262 |
| |
|
263 |
| } |
|
264 |
| |
|
265 |
| |
|
266 |
44091
| public Object getParentNode(Object o) {
|
|
267 |
| |
|
268 |
44091
| Node n;
|
|
269 |
44091
| if (o instanceof ArrayList) {
|
|
270 |
496
| n = (Node) ((List) o).get(0);
|
|
271 |
| } |
|
272 |
| else { |
|
273 |
43595
| n = (Node) o;
|
|
274 |
| } |
|
275 |
44091
| return n.getParent();
|
|
276 |
| |
|
277 |
| } |
|
278 |
| |
|
279 |
| |
|
280 |
9
| public String getTextStringValue(Object o) {
|
|
281 |
| |
|
282 |
9
| List texts = (List) o;
|
|
283 |
9
| if (texts.size() == 1) {
|
|
284 |
6
| return ((Text) texts.get(0)).getValue();
|
|
285 |
| } |
|
286 |
| else { |
|
287 |
3
| StringBuffer result = new StringBuffer();
|
|
288 |
3
| Iterator iterator = texts.iterator();
|
|
289 |
3
| while (iterator.hasNext()) {
|
|
290 |
9
| Text text = (Text) iterator.next();
|
|
291 |
9
| result.append(text.getValue());
|
|
292 |
| } |
|
293 |
3
| return result.toString();
|
|
294 |
| } |
|
295 |
| |
|
296 |
| } |
|
297 |
| |
|
298 |
| |
|
299 |
| private static class ChildIterator implements Iterator { |
|
300 |
| |
|
301 |
| private final ParentNode parent; |
|
302 |
| |
|
303 |
| private int xomIndex = 0; |
|
304 |
| private final int xomCount; |
|
305 |
| |
|
306 |
56369
| ChildIterator(ParentNode parent) {
|
|
307 |
56369
| this.parent = parent;
|
|
308 |
56369
| this.xomCount = parent.getChildCount();
|
|
309 |
| } |
|
310 |
| |
|
311 |
| |
|
312 |
2833
| ChildIterator(ParentNode parent, int startNode) {
|
|
313 |
2833
| this.parent = parent;
|
|
314 |
2833
| this.xomIndex = startNode;
|
|
315 |
2833
| this.xomCount = parent.getChildCount();
|
|
316 |
| } |
|
317 |
| |
|
318 |
| |
|
319 |
382685
| public boolean hasNext() {
|
|
320 |
| |
|
321 |
382685
| for (int i = xomIndex; i < xomCount; i++) {
|
|
322 |
325935
| Node next = parent.getChild(i);
|
|
323 |
325935
| if (next.isText()) {
|
|
324 |
214690
| if (! ((Text) next).isEmpty()) {
|
|
325 |
214671
| return true;
|
|
326 |
| } |
|
327 |
| } |
|
328 |
111245
| else return true;
|
|
329 |
| } |
|
330 |
56769
| return false;
|
|
331 |
| |
|
332 |
| } |
|
333 |
| |
|
334 |
| |
|
335 |
175211
| public Object next() {
|
|
336 |
| |
|
337 |
175211
| Object result;
|
|
338 |
175211
| Node next = parent.getChild(xomIndex++);
|
|
339 |
175211
| if (next.isText()) {
|
|
340 |
113675
| Text t = (Text) next;
|
|
341 |
| |
|
342 |
113675
| boolean empty = t.isEmpty();
|
|
343 |
113675
| List texts = new ArrayList(1);
|
|
344 |
113675
| texts.add(t);
|
|
345 |
113675
| while (xomIndex < xomCount) {
|
|
346 |
60528
| Node nextText = parent.getChild(xomIndex);
|
|
347 |
60501
| if (! nextText.isText()) break;
|
|
348 |
27
| xomIndex++;
|
|
349 |
27
| texts.add(nextText);
|
|
350 |
27
| if (empty) {
|
|
351 |
8
| if (! ((Text) nextText).isEmpty()) {
|
|
352 |
6
| empty = false;
|
|
353 |
| } |
|
354 |
| } |
|
355 |
| } |
|
356 |
| |
|
357 |
4
| if (empty) return next();
|
|
358 |
113671
| else result = texts;
|
|
359 |
| } |
|
360 |
61536
| else if (next.isDocType()) {
|
|
361 |
21
| return next();
|
|
362 |
| } |
|
363 |
| else { |
|
364 |
61515
| result = next;
|
|
365 |
| } |
|
366 |
175186
| return result;
|
|
367 |
| |
|
368 |
| } |
|
369 |
| |
|
370 |
0
| public void remove() {
|
|
371 |
0
| throw new UnsupportedOperationException();
|
|
372 |
| } |
|
373 |
| |
|
374 |
| } |
|
375 |
| |
|
376 |
| |
|
377 |
| private static class NamedChildIterator implements Iterator { |
|
378 |
| |
|
379 |
| private final ParentNode parent; |
|
380 |
| |
|
381 |
| private int index = -1; |
|
382 |
| private final int xomCount; |
|
383 |
| private Element next; |
|
384 |
| private final String localName; |
|
385 |
| private final String URI; |
|
386 |
| |
|
387 |
6268
| NamedChildIterator(ParentNode parent, String localName, String prefix, String namespaceURI) {
|
|
388 |
6268
| this.parent = parent;
|
|
389 |
6268
| this.xomCount = parent.getChildCount();
|
|
390 |
6268
| this.localName = localName;
|
|
391 |
6235
| if (namespaceURI == null) this.URI = "";
|
|
392 |
33
| else this.URI = namespaceURI;
|
|
393 |
| |
|
394 |
6268
| findNext();
|
|
395 |
| } |
|
396 |
| |
|
397 |
9415
| private void findNext() {
|
|
398 |
| |
|
399 |
9415
| while (++index < xomCount) {
|
|
400 |
26705
| Node next = parent.getChild(index);
|
|
401 |
26705
| if (next.isElement()) {
|
|
402 |
10801
| Element element = (Element) next;
|
|
403 |
10801
| String elementNamespace = element.getNamespaceURI();
|
|
404 |
10801
| if (elementNamespace.equals(URI)) {
|
|
405 |
| |
|
406 |
| |
|
407 |
| |
|
408 |
10776
| if (element.getLocalName().equals(localName)) {
|
|
409 |
3147
| this.next = element;
|
|
410 |
3147
| return;
|
|
411 |
| } |
|
412 |
| } |
|
413 |
| } |
|
414 |
| } |
|
415 |
6268
| next = null;
|
|
416 |
| } |
|
417 |
| |
|
418 |
10396
| public boolean hasNext() {
|
|
419 |
10396
| return next != null;
|
|
420 |
| } |
|
421 |
| |
|
422 |
| |
|
423 |
3147
| public Object next() {
|
|
424 |
| |
|
425 |
0
| if (next == null) throw new NoSuchElementException();
|
|
426 |
3147
| Object result = next;
|
|
427 |
3147
| findNext();
|
|
428 |
3147
| return result;
|
|
429 |
| } |
|
430 |
| |
|
431 |
0
| public void remove() {
|
|
432 |
0
| throw new UnsupportedOperationException();
|
|
433 |
| } |
|
434 |
| |
|
435 |
| } |
|
436 |
| |
|
437 |
| |
|
438 |
46741
| public String getElementNamespaceUri(Object element) {
|
|
439 |
46741
| return ((Element) element).getNamespaceURI();
|
|
440 |
| } |
|
441 |
| |
|
442 |
| |
|
443 |
| |
|
444 |
46972
| public String getElementName(Object element) {
|
|
445 |
46972
| return ((Element) element).getLocalName();
|
|
446 |
| } |
|
447 |
| |
|
448 |
827
| public String getElementQName(Object element) {
|
|
449 |
827
| return ((Element) element).getQualifiedName();
|
|
450 |
| } |
|
451 |
| |
|
452 |
| |
|
453 |
87
| public String getAttributeNamespaceUri(Object attr) {
|
|
454 |
87
| Attribute attribute = (Attribute) attr;
|
|
455 |
87
| return attribute.getNamespaceURI();
|
|
456 |
| } |
|
457 |
| |
|
458 |
| |
|
459 |
| |
|
460 |
948
| public String getAttributeName(Object attr) {
|
|
461 |
948
| Attribute attribute = (Attribute) attr;
|
|
462 |
948
| return attribute.getLocalName();
|
|
463 |
| } |
|
464 |
| |
|
465 |
| |
|
466 |
2
| public String getAttributeQName(Object attr) {
|
|
467 |
2
| Attribute attribute = (Attribute) attr;
|
|
468 |
2
| return attribute.getQualifiedName();
|
|
469 |
| } |
|
470 |
| |
|
471 |
5
| public String getProcessingInstructionData(Object o) {
|
|
472 |
5
| ProcessingInstruction pi = (ProcessingInstruction) o;
|
|
473 |
5
| return pi.getValue();
|
|
474 |
| } |
|
475 |
| |
|
476 |
| |
|
477 |
9
| public String getProcessingInstructionTarget(Object o) {
|
|
478 |
9
| ProcessingInstruction pi = (ProcessingInstruction) o;
|
|
479 |
9
| return pi.getTarget();
|
|
480 |
| } |
|
481 |
| |
|
482 |
| |
|
483 |
6268
| public boolean isDocument(Object object) {
|
|
484 |
6268
| return object instanceof Document || object instanceof DocumentFragment;
|
|
485 |
| } |
|
486 |
| |
|
487 |
| |
|
488 |
149810
| public boolean isElement(Object object) {
|
|
489 |
149810
| return object instanceof Element;
|
|
490 |
| } |
|
491 |
| |
|
492 |
| |
|
493 |
12927
| public boolean isAttribute(Object object) {
|
|
494 |
12927
| return object instanceof Attribute;
|
|
495 |
| } |
|
496 |
| |
|
497 |
| |
|
498 |
12032
| public boolean isNamespace(Object object) {
|
|
499 |
12032
| return object instanceof Namespace;
|
|
500 |
| } |
|
501 |
| |
|
502 |
| |
|
503 |
5605
| public boolean isComment(Object object) {
|
|
504 |
5605
| return object instanceof Comment;
|
|
505 |
| } |
|
506 |
| |
|
507 |
| |
|
508 |
100551
| public boolean isText(Object object) {
|
|
509 |
| |
|
510 |
| |
|
511 |
| |
|
512 |
100551
| if (object instanceof ArrayList) {
|
|
513 |
88355
| Iterator iterator = ((List) object).iterator();
|
|
514 |
88355
| while (iterator.hasNext()) {
|
|
515 |
259
| if (! (iterator.next() instanceof Text)) return false;
|
|
516 |
| } |
|
517 |
88096
| return true;
|
|
518 |
| } |
|
519 |
12196
| return false;
|
|
520 |
| } |
|
521 |
| |
|
522 |
| |
|
523 |
5577
| public boolean isProcessingInstruction(Object object) {
|
|
524 |
5577
| return object instanceof ProcessingInstruction;
|
|
525 |
| } |
|
526 |
| |
|
527 |
| |
|
528 |
4
| public String getCommentStringValue(Object comment) {
|
|
529 |
4
| return ((Comment) comment).getValue();
|
|
530 |
| } |
|
531 |
| |
|
532 |
| |
|
533 |
271
| public String getElementStringValue(Object element) {
|
|
534 |
271
| return ((Element) element).getValue();
|
|
535 |
| } |
|
536 |
| |
|
537 |
| |
|
538 |
477
| public String getAttributeStringValue(Object attribute) {
|
|
539 |
477
| return ((Attribute) attribute).getValue();
|
|
540 |
| } |
|
541 |
| |
|
542 |
| |
|
543 |
0
| public XPath parseXPath(String expression) throws JaxenException {
|
|
544 |
0
| return new JaxenConnector(expression);
|
|
545 |
| } |
|
546 |
| |
|
547 |
| |
|
548 |
16061
| public Iterator getChildAxisIterator(Object parent, String localName, String namespacePrefix, String namespaceURI)
|
|
549 |
| throws UnsupportedAxisException { |
|
550 |
| |
|
551 |
16061
| if (parent instanceof ParentNode) {
|
|
552 |
6268
| return new NamedChildIterator((ParentNode) parent, localName, namespacePrefix, namespaceURI);
|
|
553 |
| } |
|
554 |
9793
| return JaxenConstants.EMPTY_ITERATOR;
|
|
555 |
| |
|
556 |
| } |
|
557 |
| |
|
558 |
| |
|
559 |
1537
| public Iterator getAttributeAxisIterator(Object contextNode, String localName, String namespacePrefix, String namespaceURI)
|
|
560 |
| throws UnsupportedAxisException { |
|
561 |
| |
|
562 |
| |
|
563 |
| |
|
564 |
| |
|
565 |
1537
| try {
|
|
566 |
1537
| Element element = (Element) contextNode;
|
|
567 |
1515
| Attribute result = null;
|
|
568 |
1515
| if (namespaceURI == null) {
|
|
569 |
1511
| result = element.getAttribute(localName);
|
|
570 |
| } |
|
571 |
| else { |
|
572 |
4
| result = element.getAttribute(localName, namespaceURI);
|
|
573 |
| } |
|
574 |
| |
|
575 |
985
| if (result == null) return JaxenConstants.EMPTY_ITERATOR;
|
|
576 |
| |
|
577 |
530
| return new SingleObjectIterator(result);
|
|
578 |
| } |
|
579 |
| catch (ClassCastException ex) { |
|
580 |
22
| return JaxenConstants.EMPTY_ITERATOR;
|
|
581 |
| } |
|
582 |
| |
|
583 |
| } |
|
584 |
| |
|
585 |
| |
|
586 |
| } |