View Javadoc

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