1 /*
2 * Copyright 2001-2005 (C) MetaStuff, Ltd. All Rights Reserved.
3 *
4 * This software is open source.
5 * See the bottom of this file for the licence.
6 */
7
8 package org.dom4j;
9
10 import java.io.IOException;
11 import java.io.Writer;
12 import java.util.List;
13
14 /**
15 * <p>
16 * <code>Node</code> defines the polymorphic behavior for all XML nodes in a
17 * dom4j tree.
18 * </p>
19 *
20 * <p>
21 * A node can be output as its XML format, can be detached from its position in
22 * a document and can have XPath expressions evaluated on itself.
23 * </p>
24 *
25 * <p>
26 * A node may optionally support the parent relationship and may be read only.
27 * </p>
28 *
29 * @author <a href="mailto:jstrachan@apache.org">James Strachan </a>
30 * @version $Revision: 1.31 $
31 *
32 * @see #supportsParent
33 * @see #isReadOnly
34 */
35 public interface Node extends Cloneable {
36
37 /**
38 * <p>
39 * <code>supportsParent</code> returns true if this node supports the
40 * parent relationship.
41 * </p>
42 *
43 * <p>
44 * Some XML tree implementations are singly linked and only support downward
45 * navigation through children relationships. The default case is that both
46 * parent and children relationships are supported though for memory and
47 * performance reasons the parent relationship may not be supported.
48 * </p>
49 *
50 * @return true if this node supports the parent relationship or false it is
51 * not supported
52 */
53 boolean supportsParent();
54
55 /**
56 * <p>
57 * <code>getParent</code> returns the parent <code>Element</code> if
58 * this node supports the parent relationship or null if it is the root
59 * element or does not support the parent relationship.
60 * </p>
61 *
62 * <p>
63 * This method is an optional feature and may not be supported for all
64 * <code>Node</code> implementations.
65 * </p>
66 *
67 * @return the parent of this node or null if it is the root of the tree or
68 * the parent relationship is not supported.
69 */
70 Element getParent();
71
72 /**
73 * <p>
74 * <code>setParent</code> sets the parent relationship of this node if the
75 * parent relationship is supported or does nothing if the parent
76 * relationship is not supported.
77 * </p>
78 *
79 * <p>
80 * This method should only be called from inside an <code>Element</code>
81 * implementation method and is not intended for general use.
82 * </p>
83 *
84 * @param parent
85 * is the new parent of this node.
86 */
87 void setParent(Element parent);
88
89 /**
90 * <p>
91 * <code>getDocument</code> returns the <code>Document</code> that this
92 * <code>Node</code> is part of if this node supports the parent
93 * relationship.
94 * </p>
95 *
96 * <p>
97 * This method is an optional feature and may not be supported for all
98 * <code>Node</code> implementations.
99 * </p>
100 *
101 * @return the document of this node or null if this feature is not
102 * supported or the node is not associated with a
103 * <code>Document</code>
104 */
105 Document getDocument();
106
107 /**
108 * <p>
109 * <code>setDocument</code> sets the document of this node if the parent
110 * relationship is supported or does nothing if the parent relationship is
111 * not supported.
112 * </p>
113 *
114 * <p>
115 * This method should only be called from inside a <code>Document</code>
116 * implementation method and is not intended for general use.
117 * </p>
118 *
119 * @param document
120 * is the new document of this node.
121 */
122 void setDocument(Document document);
123
124 /**
125 * <p>
126 * <code>isReadOnly</code> returns true if this node is read only and
127 * cannot be modified. Any attempt to modify a read-only <code>Node</code>
128 * will result in an <code>UnsupportedOperationException</code> being
129 * thrown.
130 * </p>
131 *
132 * @return true if this <code>Node</code> is read only and cannot be
133 * modified otherwise false.
134 */
135 boolean isReadOnly();
136
137 /**
138 * <p>
139 * <code>hasContent</code> returns true if this node is a Branch (either
140 * an Element or a Document) and it contains at least one content node such
141 * as a child Element or Text node.
142 * </p>
143 *
144 * @return true if this <code>Node</code> is a Branch with a nodeCount()
145 * of one or more.
146 */
147 boolean hasContent();
148
149 /**
150 * <p>
151 * <code>getName</code> returns the name of this node. This is the XML
152 * local name of the element, attribute, entity or processing instruction.
153 * For CDATA and Text nodes this method will return null.
154 * </p>
155 *
156 * @return the XML name of this node
157 */
158 String getName();
159
160 /**
161 * <p>
162 * Sets the text data of this node or this method will throw an
163 * <code>UnsupportedOperationException</code> if it is read-only.
164 * </p>
165 *
166 * @param name
167 * is the new name of this node
168 */
169 void setName(String name);
170
171 /**
172 * <p>
173 * Returns the text of this node.
174 * </p>
175 *
176 * @return the text for this node.
177 */
178 String getText();
179
180 /**
181 * <p>
182 * Sets the text data of this node or this method will throw an
183 * <code>UnsupportedOperationException</code> if it is read-only.
184 * </p>
185 *
186 * @param text
187 * is the new textual value of this node
188 */
189 void setText(String text);
190
191 /**
192 * Returns the XPath string-value of this node. The behaviour of this method
193 * is defined in the <a href="http://www.w3.org/TR/xpath">XPath
194 * specification </a>.
195 *
196 * @return the text from all the child Text and Element nodes appended
197 * together.
198 */
199 String getStringValue();
200
201 /**
202 * <p>
203 * Returns the XPath expression which will return a node set containing the
204 * given node such as /a/b/@c. No indexing will be used to restrict the
205 * path if multiple elements with the same name occur on the path.
206 * </p>
207 *
208 * @return the XPath expression which will return a nodeset containing at
209 * least this node.
210 */
211 String getPath();
212
213 /**
214 * Returns the relative XPath expression which will return a node set
215 * containing the given node such as a/b/@c. No indexing will be used to
216 * restrict the path if multiple elements with the same name occur on the
217 * path.
218 *
219 * @param context
220 * is the parent context from which the relative path should
221 * start. If the context is null or the context is not an
222 * ancestor of this node then the path will be absolute and start
223 * from the document and so begin with the '/' character.
224 *
225 * @return the XPath expression relative to the given context which will
226 * return a nodeset containing at least this node.
227 */
228 String getPath(Element context);
229
230 /**
231 * <p>
232 * Returns the XPath expression which will return a nodeset of one node
233 * which is the current node. This method will use the XPath index operator
234 * to restrict the path if multiple elements with the same name occur on the
235 * path.
236 * </p>
237 *
238 * @return the XPath expression which will return a nodeset containing just
239 * this node.
240 */
241 String getUniquePath();
242
243 /**
244 * <p>
245 * Returns the relative unique XPath expression from the given context which
246 * will return a nodeset of one node which is the current node. This method
247 * will use the XPath index operator to restrict the path if multiple
248 * elements with the same name occur on the path.
249 * </p>
250 *
251 * @param context
252 * is the parent context from which the path should start. If the
253 * context is null or the context is not an ancestor of this node
254 * then the path will start from the document and so begin with
255 * the '/' character.
256 *
257 * @return the XPath expression relative to the given context which will
258 * return a nodeset containing just this node.
259 */
260 String getUniquePath(Element context);
261
262 /**
263 * <p>
264 * <code>asXML</code> returns the textual XML representation of this node.
265 * </p>
266 *
267 * @return the XML representation of this node
268 */
269 String asXML();
270
271 /**
272 * <p>
273 * <code>write</code> writes this node as the default XML notation for
274 * this node. If you wish to control the XML output (such as for pretty
275 * printing, changing the indentation policy etc.) then please use {@link
276 * org.dom4j.io.XMLWriter} or its derivations.
277 * </p>
278 *
279 * @param writer
280 * is the <code>Writer</code> to output the XML to
281 *
282 * @throws IOException
283 * DOCUMENT ME!
284 */
285 void write(Writer writer) throws IOException;
286
287 /**
288 * Returns the type of this node as constant from {@link NodeType} enum.
289 *
290 * @return the type of this node
291 */
292 NodeType getNodeTypeEnum();
293
294 /**
295 * Returns the code according to the type of node. This makes processing
296 * nodes polymorphically much easier as the switch statement can be used
297 * instead of multiple if (instanceof) statements.
298 *
299 * @return a W3C DOM complient code for the node type such as ELEMENT_NODE
300 * or ATTRIBUTE_NODE
301 */
302 short getNodeType();
303
304 /**
305 * Returns the name of the type of this node such as "Document", "Element",
306 * "Attribute" or "Text"
307 *
308 * @return the name of the type of this node
309 */
310 String getNodeTypeName();
311
312 /**
313 * <p>
314 * Removes this node from its parent if there is one. If this node is the
315 * root element of a document then it is removed from the document as well.
316 * </p>
317 *
318 * <p>
319 * This method is useful if you want to remove a node from its source
320 * document and add it to another document. For example
321 * </p>
322 * <code> Node node = ...; Element someOtherElement = ...;
323 * someOtherElement.add( node.detach() ); </code>
324 *
325 * @return the node that has been removed from its parent node if any and
326 * its document if any.
327 */
328 Node detach();
329
330 /**
331 * <p>
332 * <code>selectNodes</code> evaluates an XPath expression and returns the
333 * result as a <code>List</code> of <code>Node</code> instances or
334 * <code>String</code> instances depending on the XPath expression.
335 * </p>
336 *
337 * @param xpathExpression
338 * is the XPath expression to be evaluated
339 *
340 * @return the list of <code>Node</code> or <code>String</code>
341 * instances depending on the XPath expression
342 */
343 List<? extends Node> selectNodes(String xpathExpression);
344
345 /**
346 * <p>
347 * <code>selectObject</code> evaluates an XPath expression and returns the
348 * result as an {@link Object}. The object returned can either be a {@link
349 * List} of one or more {@link Node}instances or a scalar object like a
350 * {@link String}or a {@link Number}instance depending on the XPath
351 * expression.
352 * </p>
353 *
354 * @param xpathExpression
355 * is the XPath expression to be evaluated
356 *
357 * @return the value of the XPath expression as a {@link List}of {@link
358 * Node} instances, a {@link String}or a {@link Number}instance
359 * depending on the XPath expression.
360 */
361 Object selectObject(String xpathExpression);
362
363 /**
364 * <p>
365 * <code>selectNodes</code> evaluates an XPath expression then sorts the
366 * results using a secondary XPath expression Returns a sorted
367 * <code>List</code> of <code>Node</code> instances.
368 * </p>
369 *
370 * @param xpathExpression
371 * is the XPath expression to be evaluated
372 * @param comparisonXPathExpression
373 * is the XPath expression used to compare the results by for
374 * sorting
375 *
376 * @return the list of <code>Node</code> instances sorted by the
377 * comparisonXPathExpression
378 */
379 List<? extends Node> selectNodes(String xpathExpression, String comparisonXPathExpression);
380
381 /**
382 * <p>
383 * <code>selectNodes</code> evaluates an XPath expression then sorts the
384 * results using a secondary XPath expression Returns a sorted
385 * <code>List</code> of <code>Node</code> instances.
386 * </p>
387 *
388 * @param xpathExpression
389 * is the XPath expression to be evaluated
390 * @param comparisonXPathExpression
391 * is the XPath expression used to compare the results by for
392 * sorting
393 * @param removeDuplicates
394 * if this parameter is true then duplicate values (using the
395 * comparisonXPathExpression) are removed from the result List.
396 *
397 * @return the list of <code>Node</code> instances sorted by the
398 * comparisonXPathExpression
399 */
400 List<? extends Node> selectNodes(String xpathExpression, String comparisonXPathExpression,
401 boolean removeDuplicates);
402
403 /**
404 * <p>
405 * <code>selectSingleNode</code> evaluates an XPath expression and returns
406 * the result as a single <code>Node</code> instance.
407 * </p>
408 *
409 * @param xpathExpression
410 * is the XPath expression to be evaluated
411 *
412 * @return the <code>Node</code> matching the XPath expression
413 */
414 Node selectSingleNode(String xpathExpression);
415
416 /**
417 * <p>
418 * <code>valueOf</code> evaluates an XPath expression and returns the
419 * textual representation of the results the XPath string-value of this
420 * node. The string-value for a given node type is defined in the <a
421 * href="http://www.w3.org/TR/xpath">XPath specification </a>.
422 * </p>
423 *
424 * @param xpathExpression
425 * is the XPath expression to be evaluated
426 *
427 * @return the string-value representation of the results of the XPath
428 * expression
429 */
430 String valueOf(String xpathExpression);
431
432 /**
433 * <p>
434 * <code>numberValueOf</code> evaluates an XPath expression and returns
435 * the numeric value of the XPath expression if the XPath expression results
436 * in a number, or null if the result is not a number.
437 * </p>
438 *
439 * @param xpathExpression
440 * is the XPath expression to be evaluated
441 *
442 * @return the numeric result of the XPath expression or null if the result
443 * is not a number.
444 */
445 Number numberValueOf(String xpathExpression);
446
447 /**
448 * <p>
449 * <code>matches</code> returns true if evaluating the given XPath
450 * expression on this node returns a non-empty node set containing this
451 * node.
452 * </p>
453 *
454 * <p>
455 * This method does not behave like the <xsl:if> element - if you want
456 * that behaviour, to evaluate if an XPath expression matches something,
457 * then you can use the following code to be equivalent...
458 * </p>
459 * <code>if ( node.selectSingleNode( "/some/path" ) != nulll )</code>
460 *
461 * @param xpathExpression
462 * is an XPath expression
463 *
464 * @return true if this node is returned by the given XPath expression
465 */
466 boolean matches(String xpathExpression);
467
468 /**
469 * <p>
470 * <code>createXPath</code> creates an XPath object for the given
471 * xpathExpression. The XPath object allows the variable context to be
472 * specified.
473 * </p>
474 *
475 * @param xpathExpression
476 * is the XPath expression to be evaluated
477 *
478 * @return an XPath object represeting the given expression
479 *
480 * @throws InvalidXPathException
481 * if the XPath expression is invalid
482 */
483 XPath createXPath(String xpathExpression) throws InvalidXPathException;
484
485 /**
486 * <p>
487 * <code>asXPathResult</code> returns a version of this node which is
488 * capable of being an XPath result. The result of an XPath expression
489 * should always support the parent relationship, whether the original XML
490 * tree was singly or doubly linked. If the node does not support the parent
491 * relationship then a new node will be created which is linked to its
492 * parent and returned.
493 * </p>
494 *
495 * @param parent
496 * DOCUMENT ME!
497 *
498 * @return a <code>Node</code> which supports the parent relationship
499 */
500 Node asXPathResult(Element parent);
501
502 /**
503 * <p>
504 * <code>accept</code> is the method used in the Visitor Pattern.
505 * </p>
506 *
507 * @param visitor
508 * is the visitor in the Visitor Pattern
509 */
510 void accept(Visitor visitor);
511
512 /**
513 * <p>
514 * <code>clone</code> will return a deep clone or if this node is
515 * read-only then clone will return the same instance.
516 * </p>
517 *
518 * @return a deep clone of myself or myself if I am read only.
519 */
520 Object clone();
521 }
522
523 /*
524 * Redistribution and use of this software and associated documentation
525 * ("Software"), with or without modification, are permitted provided that the
526 * following conditions are met:
527 *
528 * 1. Redistributions of source code must retain copyright statements and
529 * notices. Redistributions must also contain a copy of this document.
530 *
531 * 2. Redistributions in binary form must reproduce the above copyright notice,
532 * this list of conditions and the following disclaimer in the documentation
533 * and/or other materials provided with the distribution.
534 *
535 * 3. The name "DOM4J" must not be used to endorse or promote products derived
536 * from this Software without prior written permission of MetaStuff, Ltd. For
537 * written permission, please contact dom4j-info@metastuff.com.
538 *
539 * 4. Products derived from this Software may not be called "DOM4J" nor may
540 * "DOM4J" appear in their names without prior written permission of MetaStuff,
541 * Ltd. DOM4J is a registered trademark of MetaStuff, Ltd.
542 *
543 * 5. Due credit should be given to the DOM4J Project - http://www.dom4j.org
544 *
545 * THIS SOFTWARE IS PROVIDED BY METASTUFF, LTD. AND CONTRIBUTORS ``AS IS'' AND
546 * ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
547 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
548 * ARE DISCLAIMED. IN NO EVENT SHALL METASTUFF, LTD. OR ITS CONTRIBUTORS BE
549 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
550 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
551 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
552 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
553 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
554 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
555 * POSSIBILITY OF SUCH DAMAGE.
556 *
557 * Copyright 2001-2005 (C) MetaStuff, Ltd. All Rights Reserved.
558 */