By default (when no XML SAX and DOM 2 present) parsing the properties stream with simple nanoXML parser
4 * $Date: 2002/03/24 10:27:59 $
5 * $Name: RELEASE_2_2_1 $
7 * This file is part of NanoXML 2 Lite.
8 * Copyright (C) 2000-2002 Marc De Scheemaecker, All Rights Reserved.
10 * This software is provided 'as-is', without any express or implied warranty.
11 * In no event will the authors be held liable for any damages arising from the
12 * use of this software.
14 * Permission is granted to anyone to use this software for any purpose,
15 * including commercial applications, and to alter it and redistribute it
16 * freely, subject to the following restrictions:
18 * 1. The origin of this software must not be misrepresented; you must not
19 * claim that you wrote the original software. If you use this software in
20 * a product, an acknowledgment in the product documentation would be
21 * appreciated but is not required.
23 * 2. Altered source versions must be plainly marked as such, and must not be
24 * misrepresented as being the original software.
26 * 3. This notice may not be removed or altered from any source distribution.
27 *****************************************************************************/
33 import java.io.ByteArrayOutputStream;
34 import java.io.CharArrayReader;
35 import java.io.IOException;
36 import java.io.OutputStreamWriter;
37 import java.io.Reader;
38 import java.io.StringReader;
39 import java.io.Writer;
40 import java.util.Enumeration;
41 import java.util.Hashtable;
42 import java.util.Vector;
46 * XMLElement is a representation of an XML object. The object is able to parse
49 * <DT><B>Parsing XML Data</B></DT>
51 * You can parse XML data using the following code:
53 * XMLElement xml = new XMLElement();<BR>
54 * FileReader reader = new FileReader("filename.xml");<BR>
55 * xml.parseFromReader(reader);
56 * </CODE></UL></DD></DL>
57 * <DL><DT><B>Retrieving Attributes</B></DT>
59 * You can enumerate the attributes of an element using the method
60 * {@link #enumerateAttributeNames() enumerateAttributeNames}.
61 * The attribute values can be retrieved using the method
62 * {@link #getStringAttribute(java.lang.String) getStringAttribute}.
63 * The following example shows how to list the attributes of an element:
65 * XMLElement element = ...;<BR>
66 * Enumeration enumV = element.getAttributeNames();<BR>
67 * while (enumV.hasMoreElements()) {<BR>
68 * String key = (String) enumV.nextElement();<BR>
69 * String value = element.getStringAttribute(key);<BR>
70 * System.out.println(key + " = " + value);<BR>
72 * </CODE></UL></DD></DL>
73 * <DL><DT><B>Retrieving Child Elements</B></DT>
75 * You can enumerate the children of an element using
76 * {@link #enumerateChildren() enumerateChildren}.
77 * The number of child elements can be retrieved using
78 * {@link #countChildren() countChildren}.
80 * <DL><DT><B>Elements Containing Character Data</B></DT>
82 * If an elements contains character data, like in the following example:
84 * <title>The Title</title>
86 * you can retrieve that data using the method
87 * {@link #getContent() getContent}.
89 * <DL><DT><B>Subclassing XMLElement</B></DT>
91 * When subclassing XMLElement, you need to override the method
92 * {@link #createAnotherElement() createAnotherElement}
93 * which has to return a new copy of the receiver.
97 * @see nanoxml.XMLParseException
99 * @author Marc De Scheemaecker
100 * <<A href="mailto:cyberelf@mac.com">cyberelf@mac.com</A>>
101 * @version $Name: RELEASE_2_2_1 $, $Revision: 1.4 $
106 * Serialization serial version ID.
108 static final long serialVersionUID = 6685035139346394777L;
112 * Major version of NanoXML. Classes with the same major and minor
113 * version are binary compatible. Classes with the same major version
114 * are source compatible. If the major version is different, you may
115 * need to modify the client source code.
117 * @see nanoxml.XMLElement#NANOXML_MINOR_VERSION
119 public static final int NANOXML_MAJOR_VERSION = 2;
123 * Minor version of NanoXML. Classes with the same major and minor
124 * version are binary compatible. Classes with the same major version
125 * are source compatible. If the major version is different, you may
126 * need to modify the client source code.
128 * @see nanoxml.XMLElement#NANOXML_MAJOR_VERSION
130 public static final int NANOXML_MINOR_VERSION = 2;
134 * The attributes given to the element.
136 * <dl><dt><b>Invariants:</b></dt><dd>
137 * <ul><li>The field can be empty.
138 * <li>The field is never <code>null</code>.
139 * <li>The keys and the values are strings.
142 private Hashtable attributes;
146 * Child elements of the element.
148 * <dl><dt><b>Invariants:</b></dt><dd>
149 * <ul><li>The field can be empty.
150 * <li>The field is never <code>null</code>.
151 * <li>The elements are instances of <code>XMLElement</code>
152 * or a subclass of <code>XMLElement</code>.
155 private Vector children;
159 * The name of the element.
161 * <dl><dt><b>Invariants:</b></dt><dd>
162 * <ul><li>The field is <code>null</code> iff the element is not
163 * initialized by either parse or setName.
164 * <li>If the field is not <code>null</code>, it's not empty.
165 * <li>If the field is not <code>null</code>, it contains a valid
173 * The #PCDATA content of the object.
175 * <dl><dt><b>Invariants:</b></dt><dd>
176 * <ul><li>The field is <code>null</code> iff the element is not a
178 * <li>The field can be any string, including the empty string.
181 private String contents;
185 * Conversion table for &...; entities. The keys are the entity names
186 * without the & and ; delimiters.
188 * <dl><dt><b>Invariants:</b></dt><dd>
189 * <ul><li>The field is never <code>null</code>.
190 * <li>The field always contains the following associations:
191 * "lt" => "<", "gt" => ">",
192 * "quot" => "\"", "apos" => "'",
193 * "amp" => "&"
194 * <li>The keys are strings
195 * <li>The values are char arrays
198 private Hashtable entities;
202 * The line number where the element starts.
204 * <dl><dt><b>Invariants:</b></dt><dd>
205 * <ul><li><code>lineNr >= 0</code>
212 * <code>true</code> if the case of the element and attribute names
213 * are case insensitive.
215 private boolean ignoreCase;
219 * <code>true</code> if the leading and trailing whitespace of #PCDATA
220 * sections have to be ignored.
222 private boolean ignoreWhitespace;
226 * Character read too much.
227 * This character provides push-back functionality to the input reader
228 * without having to use a PushbackReader.
229 * If there is no such character, this field is '\0'.
231 private char charReadTooMuch;
235 * The reader provided by the caller of the parse method.
237 * <dl><dt><b>Invariants:</b></dt><dd>
238 * <ul><li>The field is not <code>null</code> while the parse method
242 private Reader reader;
246 * The current line number in the source content.
248 * <dl><dt><b>Invariants:</b></dt><dd>
249 * <ul><li>parserLineNr > 0 while the parse method is running.
252 private int parserLineNr;
256 * Creates and initializes a new XML element.
257 * Calling the construction is equivalent to:
258 * <ul><code>new XMLElement(new Hashtable(), false, true)
261 * <dl><dt><b>Postconditions:</b></dt><dd>
262 * <ul><li>countChildren() => 0
263 * <li>enumerateChildren() => empty enumeration
264 * <li>enumeratePropertyNames() => empty enumeration
265 * <li>getChildren() => empty vector
266 * <li>getContent() => ""
267 * <li>getLineNr() => 0
268 * <li>getName() => null
271 * @see nanoxml.XMLElement#XMLElement(java.util.Hashtable)
272 * XMLElement(Hashtable)
273 * @see nanoxml.XMLElement#XMLElement(boolean)
274 * @see nanoxml.XMLElement#XMLElement(java.util.Hashtable,boolean)
275 * XMLElement(Hashtable, boolean)
279 this(new Hashtable(), false, true, true);
284 * Creates and initializes a new XML element.
285 * Calling the construction is equivalent to:
286 * <ul><code>new XMLElement(entities, false, true)
290 * The entity conversion table.
292 * </dl><dl><dt><b>Preconditions:</b></dt><dd>
293 * <ul><li><code>entities != null</code>
296 * <dl><dt><b>Postconditions:</b></dt><dd>
297 * <ul><li>countChildren() => 0
298 * <li>enumerateChildren() => empty enumeration
299 * <li>enumeratePropertyNames() => empty enumeration
300 * <li>getChildren() => empty vector
301 * <li>getContent() => ""
302 * <li>getLineNr() => 0
303 * <li>getName() => null
304 * </ul></dd></dl><dl>
306 * @see nanoxml.XMLElement#XMLElement()
307 * @see nanoxml.XMLElement#XMLElement(boolean)
308 * @see nanoxml.XMLElement#XMLElement(java.util.Hashtable,boolean)
309 * XMLElement(Hashtable, boolean)
311 public XMLElement(Hashtable entities)
313 this(entities, false, true, true);
318 * Creates and initializes a new XML element.
319 * Calling the construction is equivalent to:
320 * <ul><code>new XMLElement(new Hashtable(), skipLeadingWhitespace, true)
323 * @param skipLeadingWhitespace
324 * <code>true</code> if leading and trailing whitespace in PCDATA
325 * content has to be removed.
327 * </dl><dl><dt><b>Postconditions:</b></dt><dd>
328 * <ul><li>countChildren() => 0
329 * <li>enumerateChildren() => empty enumeration
330 * <li>enumeratePropertyNames() => empty enumeration
331 * <li>getChildren() => empty vector
332 * <li>getContent() => ""
333 * <li>getLineNr() => 0
334 * <li>getName() => null
335 * </ul></dd></dl><dl>
337 * @see nanoxml.XMLElement#XMLElement()
338 * @see nanoxml.XMLElement#XMLElement(java.util.Hashtable)
339 * XMLElement(Hashtable)
340 * @see nanoxml.XMLElement#XMLElement(java.util.Hashtable,boolean)
341 * XMLElement(Hashtable, boolean)
343 public XMLElement(boolean skipLeadingWhitespace)
345 this(new Hashtable(), skipLeadingWhitespace, true, true);
350 * Creates and initializes a new XML element.
351 * Calling the construction is equivalent to:
352 * <ul><code>new XMLElement(entities, skipLeadingWhitespace, true)
356 * The entity conversion table.
357 * @param skipLeadingWhitespace
358 * <code>true</code> if leading and trailing whitespace in PCDATA
359 * content has to be removed.
361 * </dl><dl><dt><b>Preconditions:</b></dt><dd>
362 * <ul><li><code>entities != null</code>
365 * <dl><dt><b>Postconditions:</b></dt><dd>
366 * <ul><li>countChildren() => 0
367 * <li>enumerateChildren() => empty enumeration
368 * <li>enumeratePropertyNames() => empty enumeration
369 * <li>getChildren() => empty vector
370 * <li>getContent() => ""
371 * <li>getLineNr() => 0
372 * <li>getName() => null
373 * </ul></dd></dl><dl>
375 * @see nanoxml.XMLElement#XMLElement()
376 * @see nanoxml.XMLElement#XMLElement(boolean)
377 * @see nanoxml.XMLElement#XMLElement(java.util.Hashtable)
378 * XMLElement(Hashtable)
380 public XMLElement(Hashtable entities,
381 boolean skipLeadingWhitespace)
383 this(entities, skipLeadingWhitespace, true, true);
388 * Creates and initializes a new XML element.
391 * The entity conversion table.
392 * @param skipLeadingWhitespace
393 * <code>true</code> if leading and trailing whitespace in PCDATA
394 * content has to be removed.
396 * <code>true</code> if the case of element and attribute names have
399 * </dl><dl><dt><b>Preconditions:</b></dt><dd>
400 * <ul><li><code>entities != null</code>
403 * <dl><dt><b>Postconditions:</b></dt><dd>
404 * <ul><li>countChildren() => 0
405 * <li>enumerateChildren() => empty enumeration
406 * <li>enumeratePropertyNames() => empty enumeration
407 * <li>getChildren() => empty vector
408 * <li>getContent() => ""
409 * <li>getLineNr() => 0
410 * <li>getName() => null
411 * </ul></dd></dl><dl>
413 * @see nanoxml.XMLElement#XMLElement()
414 * @see nanoxml.XMLElement#XMLElement(boolean)
415 * @see nanoxml.XMLElement#XMLElement(java.util.Hashtable)
416 * XMLElement(Hashtable)
417 * @see nanoxml.XMLElement#XMLElement(java.util.Hashtable,boolean)
418 * XMLElement(Hashtable, boolean)
420 public XMLElement(Hashtable entities,
421 boolean skipLeadingWhitespace,
424 this(entities, skipLeadingWhitespace, true, ignoreCase);
429 * Creates and initializes a new XML element.
431 * This constructor should <I>only</I> be called from
432 * {@link #createAnotherElement() createAnotherElement}
433 * to create child elements.
436 * The entity conversion table.
437 * @param skipLeadingWhitespace
438 * <code>true</code> if leading and trailing whitespace in PCDATA
439 * content has to be removed.
440 * @param fillBasicConversionTable
441 * <code>true</code> if the basic entities need to be added to
444 * <code>true</code> if the case of element and attribute names have
447 * </dl><dl><dt><b>Preconditions:</b></dt><dd>
448 * <ul><li><code>entities != null</code>
449 * <li>if <code>fillBasicConversionTable == false</code>
450 * then <code>entities</code> contains at least the following
451 * entries: <code>amp</code>, <code>lt</code>, <code>gt</code>,
452 * <code>apos</code> and <code>quot</code>
455 * <dl><dt><b>Postconditions:</b></dt><dd>
456 * <ul><li>countChildren() => 0
457 * <li>enumerateChildren() => empty enumeration
458 * <li>enumeratePropertyNames() => empty enumeration
459 * <li>getChildren() => empty vector
460 * <li>getContent() => ""
461 * <li>getLineNr() => 0
462 * <li>getName() => null
463 * </ul></dd></dl><dl>
465 * @see nanoxml.XMLElement#createAnotherElement()
467 protected XMLElement(Hashtable entities,
468 boolean skipLeadingWhitespace,
469 boolean fillBasicConversionTable,
472 this.ignoreWhitespace = skipLeadingWhitespace;
473 this.ignoreCase = ignoreCase;
476 this.attributes = new Hashtable();
477 this.children = new Vector();
478 this.entities = entities;
480 Enumeration enumV = this.entities.keys();
481 while (enumV.hasMoreElements()) {
482 Object key = enumV.nextElement();
483 Object value = this.entities.get(key);
484 if (value instanceof String) {
485 value = ((String) value).toCharArray();
486 this.entities.put(key, value);
489 if (fillBasicConversionTable) {
490 this.entities.put("amp", new char[] { '&' });
491 this.entities.put("quot", new char[] { '"' });
492 this.entities.put("apos", new char[] { '\'' });
493 this.entities.put("lt", new char[] { '<' });
494 this.entities.put("gt", new char[] { '>' });
500 * Adds a child element.
503 * The child element to add.
505 * </dl><dl><dt><b>Preconditions:</b></dt><dd>
506 * <ul><li><code>child != null</code>
507 * <li><code>child.getName() != null</code>
508 * <li><code>child</code> does not have a parent element
511 * <dl><dt><b>Postconditions:</b></dt><dd>
512 * <ul><li>countChildren() => old.countChildren() + 1
513 * <li>enumerateChildren() => old.enumerateChildren() + child
514 * <li>getChildren() => old.enumerateChildren() + child
515 * </ul></dd></dl><dl>
517 * @see nanoxml.XMLElement#countChildren()
518 * @see nanoxml.XMLElement#enumerateChildren()
519 * @see nanoxml.XMLElement#getChildren()
520 * @see nanoxml.XMLElement#removeChild(nanoxml.XMLElement)
521 * removeChild(XMLElement)
523 public void addChild(XMLElement child)
525 this.children.addElement(child);
530 * Adds or modifies an attribute.
533 * The name of the attribute.
535 * The value of the attribute.
537 * </dl><dl><dt><b>Preconditions:</b></dt><dd>
538 * <ul><li><code>name != null</code>
539 * <li><code>name</code> is a valid XML identifier
540 * <li><code>value != null</code>
543 * <dl><dt><b>Postconditions:</b></dt><dd>
544 * <ul><li>enumerateAttributeNames()
545 * => old.enumerateAttributeNames() + name
546 * <li>getAttribute(name) => value
547 * </ul></dd></dl><dl>
549 * @see nanoxml.XMLElement#setDoubleAttribute(java.lang.String, double)
550 * setDoubleAttribute(String, double)
551 * @see nanoxml.XMLElement#setIntAttribute(java.lang.String, int)
552 * setIntAttribute(String, int)
553 * @see nanoxml.XMLElement#enumerateAttributeNames()
554 * @see nanoxml.XMLElement#getAttribute(java.lang.String)
555 * getAttribute(String)
556 * @see nanoxml.XMLElement#getAttribute(java.lang.String, java.lang.Object)
557 * getAttribute(String, Object)
558 * @see nanoxml.XMLElement#getAttribute(java.lang.String,
559 * java.util.Hashtable,
560 * java.lang.String, boolean)
561 * getAttribute(String, Hashtable, String, boolean)
562 * @see nanoxml.XMLElement#getStringAttribute(java.lang.String)
563 * getStringAttribute(String)
564 * @see nanoxml.XMLElement#getStringAttribute(java.lang.String,
566 * getStringAttribute(String, String)
567 * @see nanoxml.XMLElement#getStringAttribute(java.lang.String,
568 * java.util.Hashtable,
569 * java.lang.String, boolean)
570 * getStringAttribute(String, Hashtable, String, boolean)
572 public void setAttribute(String name,
575 if (this.ignoreCase) {
576 name = name.toUpperCase();
578 this.attributes.put(name, value.toString());
583 * Adds or modifies an attribute.
586 * The name of the attribute.
588 * The value of the attribute.
590 * @deprecated Use {@link #setAttribute(java.lang.String, java.lang.Object)
591 * setAttribute} instead.
593 public void addProperty(String name,
596 this.setAttribute(name, value);
601 * Adds or modifies an attribute.
604 * The name of the attribute.
606 * The value of the attribute.
608 * </dl><dl><dt><b>Preconditions:</b></dt><dd>
609 * <ul><li><code>name != null</code>
610 * <li><code>name</code> is a valid XML identifier
613 * <dl><dt><b>Postconditions:</b></dt><dd>
614 * <ul><li>enumerateAttributeNames()
615 * => old.enumerateAttributeNames() + name
616 * <li>getIntAttribute(name) => value
617 * </ul></dd></dl><dl>
619 * @see nanoxml.XMLElement#setDoubleAttribute(java.lang.String, double)
620 * setDoubleAttribute(String, double)
621 * @see nanoxml.XMLElement#setAttribute(java.lang.String, java.lang.Object)
622 * setAttribute(String, Object)
623 * @see nanoxml.XMLElement#removeAttribute(java.lang.String)
624 * removeAttribute(String)
625 * @see nanoxml.XMLElement#enumerateAttributeNames()
626 * @see nanoxml.XMLElement#getIntAttribute(java.lang.String)
627 * getIntAttribute(String)
628 * @see nanoxml.XMLElement#getIntAttribute(java.lang.String, int)
629 * getIntAttribute(String, int)
630 * @see nanoxml.XMLElement#getIntAttribute(java.lang.String,
631 * java.util.Hashtable,
632 * java.lang.String, boolean)
633 * getIntAttribute(String, Hashtable, String, boolean)
635 public void setIntAttribute(String name,
638 if (this.ignoreCase) {
639 name = name.toUpperCase();
641 this.attributes.put(name, Integer.toString(value));
646 * Adds or modifies an attribute.
649 * The name of the attribute.
651 * The value of the attribute.
653 * @deprecated Use {@link #setIntAttribute(java.lang.String, int)
654 * setIntAttribute} instead.
656 public void addProperty(String key,
659 this.setIntAttribute(key, value);
664 * Adds or modifies an attribute.
667 * The name of the attribute.
669 * The value of the attribute.
671 * </dl><dl><dt><b>Preconditions:</b></dt><dd>
672 * <ul><li><code>name != null</code>
673 * <li><code>name</code> is a valid XML identifier
676 * <dl><dt><b>Postconditions:</b></dt><dd>
677 * <ul><li>enumerateAttributeNames()
678 * => old.enumerateAttributeNames() + name
679 * <li>getDoubleAttribute(name) => value
680 * </ul></dd></dl><dl>
682 * @see nanoxml.XMLElement#setIntAttribute(java.lang.String, int)
683 * setIntAttribute(String, int)
684 * @see nanoxml.XMLElement#setAttribute(java.lang.String, java.lang.Object)
685 * setAttribute(String, Object)
686 * @see nanoxml.XMLElement#removeAttribute(java.lang.String)
687 * removeAttribute(String)
688 * @see nanoxml.XMLElement#enumerateAttributeNames()
689 * @see nanoxml.XMLElement#getDoubleAttribute(java.lang.String)
690 * getDoubleAttribute(String)
691 * @see nanoxml.XMLElement#getDoubleAttribute(java.lang.String, double)
692 * getDoubleAttribute(String, double)
693 * @see nanoxml.XMLElement#getDoubleAttribute(java.lang.String,
694 * java.util.Hashtable,
695 * java.lang.String, boolean)
696 * getDoubleAttribute(String, Hashtable, String, boolean)
698 public void setDoubleAttribute(String name,
701 if (this.ignoreCase) {
702 name = name.toUpperCase();
704 this.attributes.put(name, Double.toString(value));
709 * Adds or modifies an attribute.
712 * The name of the attribute.
714 * The value of the attribute.
716 * @deprecated Use {@link #setDoubleAttribute(java.lang.String, double)
717 * setDoubleAttribute} instead.
719 public void addProperty(String name,
722 this.setDoubleAttribute(name, value);
727 * Returns the number of child elements of the element.
729 * <dl><dt><b>Postconditions:</b></dt><dd>
730 * <ul><li><code>result >= 0</code>
733 * @see nanoxml.XMLElement#addChild(nanoxml.XMLElement)
734 * addChild(XMLElement)
735 * @see nanoxml.XMLElement#enumerateChildren()
736 * @see nanoxml.XMLElement#getChildren()
737 * @see nanoxml.XMLElement#removeChild(nanoxml.XMLElement)
738 * removeChild(XMLElement)
740 public int countChildren()
742 return this.children.size();
747 * Enumerates the attribute names.
749 * <dl><dt><b>Postconditions:</b></dt><dd>
750 * <ul><li><code>result != null</code>
753 * @see nanoxml.XMLElement#setDoubleAttribute(java.lang.String, double)
754 * setDoubleAttribute(String, double)
755 * @see nanoxml.XMLElement#setIntAttribute(java.lang.String, int)
756 * setIntAttribute(String, int)
757 * @see nanoxml.XMLElement#setAttribute(java.lang.String, java.lang.Object)
758 * setAttribute(String, Object)
759 * @see nanoxml.XMLElement#removeAttribute(java.lang.String)
760 * removeAttribute(String)
761 * @see nanoxml.XMLElement#getAttribute(java.lang.String)
762 * getAttribute(String)
763 * @see nanoxml.XMLElement#getAttribute(java.lang.String, java.lang.Object)
764 * getAttribute(String, String)
765 * @see nanoxml.XMLElement#getAttribute(java.lang.String,
766 * java.util.Hashtable,
767 * java.lang.String, boolean)
768 * getAttribute(String, Hashtable, String, boolean)
769 * @see nanoxml.XMLElement#getStringAttribute(java.lang.String)
770 * getStringAttribute(String)
771 * @see nanoxml.XMLElement#getStringAttribute(java.lang.String,
773 * getStringAttribute(String, String)
774 * @see nanoxml.XMLElement#getStringAttribute(java.lang.String,
775 * java.util.Hashtable,
776 * java.lang.String, boolean)
777 * getStringAttribute(String, Hashtable, String, boolean)
778 * @see nanoxml.XMLElement#getIntAttribute(java.lang.String)
779 * getIntAttribute(String)
780 * @see nanoxml.XMLElement#getIntAttribute(java.lang.String, int)
781 * getIntAttribute(String, int)
782 * @see nanoxml.XMLElement#getIntAttribute(java.lang.String,
783 * java.util.Hashtable,
784 * java.lang.String, boolean)
785 * getIntAttribute(String, Hashtable, String, boolean)
786 * @see nanoxml.XMLElement#getDoubleAttribute(java.lang.String)
787 * getDoubleAttribute(String)
788 * @see nanoxml.XMLElement#getDoubleAttribute(java.lang.String, double)
789 * getDoubleAttribute(String, double)
790 * @see nanoxml.XMLElement#getDoubleAttribute(java.lang.String,
791 * java.util.Hashtable,
792 * java.lang.String, boolean)
793 * getDoubleAttribute(String, Hashtable, String, boolean)
794 * @see nanoxml.XMLElement#getBooleanAttribute(java.lang.String,
796 * java.lang.String, boolean)
797 * getBooleanAttribute(String, String, String, boolean)
799 public Enumeration enumerateAttributeNames()
801 return this.attributes.keys();
806 * Enumerates the attribute names.
808 * @deprecated Use {@link #enumerateAttributeNames()
809 * enumerateAttributeNames} instead.
811 public Enumeration enumeratePropertyNames()
813 return this.enumerateAttributeNames();
818 * Enumerates the child elements.
820 * <dl><dt><b>Postconditions:</b></dt><dd>
821 * <ul><li><code>result != null</code>
824 * @see nanoxml.XMLElement#addChild(nanoxml.XMLElement)
825 * addChild(XMLElement)
826 * @see nanoxml.XMLElement#countChildren()
827 * @see nanoxml.XMLElement#getChildren()
828 * @see nanoxml.XMLElement#removeChild(nanoxml.XMLElement)
829 * removeChild(XMLElement)
831 public Enumeration enumerateChildren()
833 return this.children.elements();
838 * Returns the child elements as a Vector. It is safe to modify this
841 * <dl><dt><b>Postconditions:</b></dt><dd>
842 * <ul><li><code>result != null</code>
845 * @see nanoxml.XMLElement#addChild(nanoxml.XMLElement)
846 * addChild(XMLElement)
847 * @see nanoxml.XMLElement#countChildren()
848 * @see nanoxml.XMLElement#enumerateChildren()
849 * @see nanoxml.XMLElement#removeChild(nanoxml.XMLElement)
850 * removeChild(XMLElement)
852 public Vector getChildren()
855 return (Vector) this.children.clone();
856 } catch (Exception e) {
857 // this never happens, however, some Java compilers are so
858 // braindead that they require this exception clause
865 * Returns the PCDATA content of the object. If there is no such content,
866 * <CODE>null</CODE> is returned.
868 * @deprecated Use {@link #getContent() getContent} instead.
870 public String getContents()
872 return this.getContent();
877 * Returns the PCDATA content of the object. If there is no such content,
878 * <CODE>null</CODE> is returned.
880 * @see nanoxml.XMLElement#setContent(java.lang.String)
883 public String getContent()
885 return this.contents;
890 * Returns the line nr in the source data on which the element is found.
891 * This method returns <code>0</code> there is no associated source data.
893 * <dl><dt><b>Postconditions:</b></dt><dd>
894 * <ul><li><code>result >= 0</code>
897 public int getLineNr()
904 * Returns an attribute of the element.
905 * If the attribute doesn't exist, <code>null</code> is returned.
907 * @param name The name of the attribute.
909 * </dl><dl><dt><b>Preconditions:</b></dt><dd>
910 * <ul><li><code>name != null</code>
911 * <li><code>name</code> is a valid XML identifier
912 * </ul></dd></dl><dl>
914 * @see nanoxml.XMLElement#setAttribute(java.lang.String, java.lang.Object)
915 * setAttribute(String, Object)
916 * @see nanoxml.XMLElement#removeAttribute(java.lang.String)
917 * removeAttribute(String)
918 * @see nanoxml.XMLElement#enumerateAttributeNames()
919 * @see nanoxml.XMLElement#getAttribute(java.lang.String, java.lang.Object)
920 * getAttribute(String, Object)
921 * @see nanoxml.XMLElement#getAttribute(java.lang.String,
922 * java.util.Hashtable,
923 * java.lang.String, boolean)
924 * getAttribute(String, Hashtable, String, boolean)
926 public Object getAttribute(String name)
928 return this.getAttribute(name, null);
933 * Returns an attribute of the element.
934 * If the attribute doesn't exist, <code>defaultValue</code> is returned.
936 * @param name The name of the attribute.
937 * @param defaultValue Key to use if the attribute is missing.
939 * </dl><dl><dt><b>Preconditions:</b></dt><dd>
940 * <ul><li><code>name != null</code>
941 * <li><code>name</code> is a valid XML identifier
942 * </ul></dd></dl><dl>
944 * @see nanoxml.XMLElement#setAttribute(java.lang.String, java.lang.Object)
945 * setAttribute(String, Object)
946 * @see nanoxml.XMLElement#removeAttribute(java.lang.String)
947 * removeAttribute(String)
948 * @see nanoxml.XMLElement#enumerateAttributeNames()
949 * @see nanoxml.XMLElement#getAttribute(java.lang.String)
950 * getAttribute(String)
951 * @see nanoxml.XMLElement#getAttribute(java.lang.String,
952 * java.util.Hashtable,
953 * java.lang.String, boolean)
954 * getAttribute(String, Hashtable, String, boolean)
956 public Object getAttribute(String name,
959 if (this.ignoreCase) {
960 name = name.toUpperCase();
962 Object value = this.attributes.get(name);
964 value = defaultValue;
971 * Returns an attribute by looking up a key in a hashtable.
972 * If the attribute doesn't exist, the value corresponding to defaultKey
975 * As an example, if valueSet contains the mapping <code>"one" =>
977 * and the element contains the attribute <code>attr="one"</code>, then
978 * <code>getAttribute("attr", mapping, defaultKey, false)</code> returns
982 * The name of the attribute.
984 * Hashtable mapping keys to values.
986 * Key to use if the attribute is missing.
987 * @param allowLiterals
988 * <code>true</code> if literals are valid.
990 * </dl><dl><dt><b>Preconditions:</b></dt><dd>
991 * <ul><li><code>name != null</code>
992 * <li><code>name</code> is a valid XML identifier
993 * <li><code>valueSet</code> != null
994 * <li>the keys of <code>valueSet</code> are strings
995 * </ul></dd></dl><dl>
997 * @see nanoxml.XMLElement#setAttribute(java.lang.String, java.lang.Object)
998 * setAttribute(String, Object)
999 * @see nanoxml.XMLElement#removeAttribute(java.lang.String)
1000 * removeAttribute(String)
1001 * @see nanoxml.XMLElement#enumerateAttributeNames()
1002 * @see nanoxml.XMLElement#getAttribute(java.lang.String)
1003 * getAttribute(String)
1004 * @see nanoxml.XMLElement#getAttribute(java.lang.String, java.lang.Object)
1005 * getAttribute(String, Object)
1007 public Object getAttribute(String name,
1010 boolean allowLiterals)
1012 if (this.ignoreCase) {
1013 name = name.toUpperCase();
1015 Object key = this.attributes.get(name);
1020 result = valueSet.get(key);
1021 if (result == null) {
1022 if (allowLiterals) {
1025 throw this.invalidValue(name, (String) key);
1033 * Returns an attribute of the element.
1034 * If the attribute doesn't exist, <code>null</code> is returned.
1036 * @param name The name of the attribute.
1038 * </dl><dl><dt><b>Preconditions:</b></dt><dd>
1039 * <ul><li><code>name != null</code>
1040 * <li><code>name</code> is a valid XML identifier
1041 * </ul></dd></dl><dl>
1043 * @see nanoxml.XMLElement#setAttribute(java.lang.String, java.lang.Object)
1044 * setAttribute(String, Object)
1045 * @see nanoxml.XMLElement#removeAttribute(java.lang.String)
1046 * removeAttribute(String)
1047 * @see nanoxml.XMLElement#enumerateAttributeNames()
1048 * @see nanoxml.XMLElement#getStringAttribute(java.lang.String,
1050 * getStringAttribute(String, String)
1051 * @see nanoxml.XMLElement#getStringAttribute(java.lang.String,
1052 * java.util.Hashtable,
1053 * java.lang.String, boolean)
1054 * getStringAttribute(String, Hashtable, String, boolean)
1056 public String getStringAttribute(String name)
1058 return this.getStringAttribute(name, null);
1063 * Returns an attribute of the element.
1064 * If the attribute doesn't exist, <code>defaultValue</code> is returned.
1066 * @param name The name of the attribute.
1067 * @param defaultValue Key to use if the attribute is missing.
1069 * </dl><dl><dt><b>Preconditions:</b></dt><dd>
1070 * <ul><li><code>name != null</code>
1071 * <li><code>name</code> is a valid XML identifier
1072 * </ul></dd></dl><dl>
1074 * @see nanoxml.XMLElement#setAttribute(java.lang.String, java.lang.Object)
1075 * setAttribute(String, Object)
1076 * @see nanoxml.XMLElement#removeAttribute(java.lang.String)
1077 * removeAttribute(String)
1078 * @see nanoxml.XMLElement#enumerateAttributeNames()
1079 * @see nanoxml.XMLElement#getStringAttribute(java.lang.String)
1080 * getStringAttribute(String)
1081 * @see nanoxml.XMLElement#getStringAttribute(java.lang.String,
1082 * java.util.Hashtable,
1083 * java.lang.String, boolean)
1084 * getStringAttribute(String, Hashtable, String, boolean)
1086 public String getStringAttribute(String name,
1087 String defaultValue)
1089 return (String) this.getAttribute(name, defaultValue);
1094 * Returns an attribute by looking up a key in a hashtable.
1095 * If the attribute doesn't exist, the value corresponding to defaultKey
1098 * As an example, if valueSet contains the mapping <code>"one" =>
1100 * and the element contains the attribute <code>attr="one"</code>, then
1101 * <code>getAttribute("attr", mapping, defaultKey, false)</code> returns
1105 * The name of the attribute.
1107 * Hashtable mapping keys to values.
1109 * Key to use if the attribute is missing.
1110 * @param allowLiterals
1111 * <code>true</code> if literals are valid.
1113 * </dl><dl><dt><b>Preconditions:</b></dt><dd>
1114 * <ul><li><code>name != null</code>
1115 * <li><code>name</code> is a valid XML identifier
1116 * <li><code>valueSet</code> != null
1117 * <li>the keys of <code>valueSet</code> are strings
1118 * <li>the values of <code>valueSet</code> are strings
1119 * </ul></dd></dl><dl>
1121 * @see nanoxml.XMLElement#setAttribute(java.lang.String, java.lang.Object)
1122 * setAttribute(String, Object)
1123 * @see nanoxml.XMLElement#removeAttribute(java.lang.String)
1124 * removeAttribute(String)
1125 * @see nanoxml.XMLElement#enumerateAttributeNames()
1126 * @see nanoxml.XMLElement#getStringAttribute(java.lang.String)
1127 * getStringAttribute(String)
1128 * @see nanoxml.XMLElement#getStringAttribute(java.lang.String,
1130 * getStringAttribute(String, String)
1132 public String getStringAttribute(String name,
1135 boolean allowLiterals)
1137 return (String) this.getAttribute(name, valueSet, defaultKey,
1143 * Returns an attribute of the element.
1144 * If the attribute doesn't exist, <code>0</code> is returned.
1146 * @param name The name of the attribute.
1148 * </dl><dl><dt><b>Preconditions:</b></dt><dd>
1149 * <ul><li><code>name != null</code>
1150 * <li><code>name</code> is a valid XML identifier
1151 * </ul></dd></dl><dl>
1153 * @see nanoxml.XMLElement#setIntAttribute(java.lang.String, int)
1154 * setIntAttribute(String, int)
1155 * @see nanoxml.XMLElement#enumerateAttributeNames()
1156 * @see nanoxml.XMLElement#getIntAttribute(java.lang.String, int)
1157 * getIntAttribute(String, int)
1158 * @see nanoxml.XMLElement#getIntAttribute(java.lang.String,
1159 * java.util.Hashtable,
1160 * java.lang.String, boolean)
1161 * getIntAttribute(String, Hashtable, String, boolean)
1163 public int getIntAttribute(String name)
1165 return this.getIntAttribute(name, 0);
1170 * Returns an attribute of the element.
1171 * If the attribute doesn't exist, <code>defaultValue</code> is returned.
1173 * @param name The name of the attribute.
1174 * @param defaultValue Key to use if the attribute is missing.
1176 * </dl><dl><dt><b>Preconditions:</b></dt><dd>
1177 * <ul><li><code>name != null</code>
1178 * <li><code>name</code> is a valid XML identifier
1179 * </ul></dd></dl><dl>
1181 * @see nanoxml.XMLElement#setIntAttribute(java.lang.String, int)
1182 * setIntAttribute(String, int)
1183 * @see nanoxml.XMLElement#enumerateAttributeNames()
1184 * @see nanoxml.XMLElement#getIntAttribute(java.lang.String)
1185 * getIntAttribute(String)
1186 * @see nanoxml.XMLElement#getIntAttribute(java.lang.String,
1187 * java.util.Hashtable,
1188 * java.lang.String, boolean)
1189 * getIntAttribute(String, Hashtable, String, boolean)
1191 public int getIntAttribute(String name,
1194 if (this.ignoreCase) {
1195 name = name.toUpperCase();
1197 String value = (String) this.attributes.get(name);
1198 if (value == null) {
1199 return defaultValue;
1202 return Integer.parseInt(value);
1203 } catch (NumberFormatException e) {
1204 throw this.invalidValue(name, value);
1211 * Returns an attribute by looking up a key in a hashtable.
1212 * If the attribute doesn't exist, the value corresponding to defaultKey
1215 * As an example, if valueSet contains the mapping <code>"one" => 1</code>
1216 * and the element contains the attribute <code>attr="one"</code>, then
1217 * <code>getIntAttribute("attr", mapping, defaultKey, false)</code> returns
1221 * The name of the attribute.
1223 * Hashtable mapping keys to values.
1225 * Key to use if the attribute is missing.
1226 * @param allowLiteralNumbers
1227 * <code>true</code> if literal numbers are valid.
1229 * </dl><dl><dt><b>Preconditions:</b></dt><dd>
1230 * <ul><li><code>name != null</code>
1231 * <li><code>name</code> is a valid XML identifier
1232 * <li><code>valueSet</code> != null
1233 * <li>the keys of <code>valueSet</code> are strings
1234 * <li>the values of <code>valueSet</code> are Integer objects
1235 * <li><code>defaultKey</code> is either <code>null</code>, a
1236 * key in <code>valueSet</code> or an integer.
1237 * </ul></dd></dl><dl>
1239 * @see nanoxml.XMLElement#setIntAttribute(java.lang.String, int)
1240 * setIntAttribute(String, int)
1241 * @see nanoxml.XMLElement#enumerateAttributeNames()
1242 * @see nanoxml.XMLElement#getIntAttribute(java.lang.String)
1243 * getIntAttribute(String)
1244 * @see nanoxml.XMLElement#getIntAttribute(java.lang.String, int)
1245 * getIntAttribute(String, int)
1247 public int getIntAttribute(String name,
1250 boolean allowLiteralNumbers)
1252 if (this.ignoreCase) {
1253 name = name.toUpperCase();
1255 Object key = this.attributes.get(name);
1261 result = (Integer) valueSet.get(key);
1262 } catch (ClassCastException e) {
1263 throw this.invalidValueSet(name);
1265 if (result == null) {
1266 if (! allowLiteralNumbers) {
1267 throw this.invalidValue(name, (String) key);
1270 result = Integer.valueOf((String) key);
1271 } catch (NumberFormatException e) {
1272 throw this.invalidValue(name, (String) key);
1275 return result.intValue();
1280 * Returns an attribute of the element.
1281 * If the attribute doesn't exist, <code>0.0</code> is returned.
1283 * @param name The name of the attribute.
1285 * </dl><dl><dt><b>Preconditions:</b></dt><dd>
1286 * <ul><li><code>name != null</code>
1287 * <li><code>name</code> is a valid XML identifier
1288 * </ul></dd></dl><dl>
1290 * @see nanoxml.XMLElement#setDoubleAttribute(java.lang.String, double)
1291 * setDoubleAttribute(String, double)
1292 * @see nanoxml.XMLElement#enumerateAttributeNames()
1293 * @see nanoxml.XMLElement#getDoubleAttribute(java.lang.String, double)
1294 * getDoubleAttribute(String, double)
1295 * @see nanoxml.XMLElement#getDoubleAttribute(java.lang.String,
1296 * java.util.Hashtable,
1297 * java.lang.String, boolean)
1298 * getDoubleAttribute(String, Hashtable, String, boolean)
1300 public double getDoubleAttribute(String name)
1302 return this.getDoubleAttribute(name, 0.);
1307 * Returns an attribute of the element.
1308 * If the attribute doesn't exist, <code>defaultValue</code> is returned.
1310 * @param name The name of the attribute.
1311 * @param defaultValue Key to use if the attribute is missing.
1313 * </dl><dl><dt><b>Preconditions:</b></dt><dd>
1314 * <ul><li><code>name != null</code>
1315 * <li><code>name</code> is a valid XML identifier
1316 * </ul></dd></dl><dl>
1318 * @see nanoxml.XMLElement#setDoubleAttribute(java.lang.String, double)
1319 * setDoubleAttribute(String, double)
1320 * @see nanoxml.XMLElement#enumerateAttributeNames()
1321 * @see nanoxml.XMLElement#getDoubleAttribute(java.lang.String)
1322 * getDoubleAttribute(String)
1323 * @see nanoxml.XMLElement#getDoubleAttribute(java.lang.String,
1324 * java.util.Hashtable,
1325 * java.lang.String, boolean)
1326 * getDoubleAttribute(String, Hashtable, String, boolean)
1328 public double getDoubleAttribute(String name,
1329 double defaultValue)
1331 if (this.ignoreCase) {
1332 name = name.toUpperCase();
1334 String value = (String) this.attributes.get(name);
1335 if (value == null) {
1336 return defaultValue;
1339 return Double.valueOf(value).doubleValue();
1340 } catch (NumberFormatException e) {
1341 throw this.invalidValue(name, value);
1348 * Returns an attribute by looking up a key in a hashtable.
1349 * If the attribute doesn't exist, the value corresponding to defaultKey
1352 * As an example, if valueSet contains the mapping <code>"one" =>
1354 * and the element contains the attribute <code>attr="one"</code>, then
1355 * <code>getDoubleAttribute("attr", mapping, defaultKey, false)</code>
1356 * returns <code>1.0</code>.
1359 * The name of the attribute.
1361 * Hashtable mapping keys to values.
1363 * Key to use if the attribute is missing.
1364 * @param allowLiteralNumbers
1365 * <code>true</code> if literal numbers are valid.
1367 * </dl><dl><dt><b>Preconditions:</b></dt><dd>
1368 * <ul><li><code>name != null</code>
1369 * <li><code>name</code> is a valid XML identifier
1370 * <li><code>valueSet != null</code>
1371 * <li>the keys of <code>valueSet</code> are strings
1372 * <li>the values of <code>valueSet</code> are Double objects
1373 * <li><code>defaultKey</code> is either <code>null</code>, a
1374 * key in <code>valueSet</code> or a double.
1375 * </ul></dd></dl><dl>
1377 * @see nanoxml.XMLElement#setDoubleAttribute(java.lang.String, double)
1378 * setDoubleAttribute(String, double)
1379 * @see nanoxml.XMLElement#enumerateAttributeNames()
1380 * @see nanoxml.XMLElement#getDoubleAttribute(java.lang.String)
1381 * getDoubleAttribute(String)
1382 * @see nanoxml.XMLElement#getDoubleAttribute(java.lang.String, double)
1383 * getDoubleAttribute(String, double)
1385 public double getDoubleAttribute(String name,
1388 boolean allowLiteralNumbers)
1390 if (this.ignoreCase) {
1391 name = name.toUpperCase();
1393 Object key = this.attributes.get(name);
1399 result = (Double) valueSet.get(key);
1400 } catch (ClassCastException e) {
1401 throw this.invalidValueSet(name);
1403 if (result == null) {
1404 if (! allowLiteralNumbers) {
1405 throw this.invalidValue(name, (String) key);
1408 result = Double.valueOf((String) key);
1409 } catch (NumberFormatException e) {
1410 throw this.invalidValue(name, (String) key);
1413 return result.doubleValue();
1418 * Returns an attribute of the element.
1419 * If the attribute doesn't exist, <code>defaultValue</code> is returned.
1420 * If the value of the attribute is equal to <code>trueValue</code>,
1421 * <code>true</code> is returned.
1422 * If the value of the attribute is equal to <code>falseValue</code>,
1423 * <code>false</code> is returned.
1424 * If the value doesn't match <code>trueValue</code> or
1425 * <code>falseValue</code>, an exception is thrown.
1427 * @param name The name of the attribute.
1428 * @param trueValue The value associated with <code>true</code>.
1429 * @param falseValue The value associated with <code>true</code>.
1430 * @param defaultValue Value to use if the attribute is missing.
1432 * </dl><dl><dt><b>Preconditions:</b></dt><dd>
1433 * <ul><li><code>name != null</code>
1434 * <li><code>name</code> is a valid XML identifier
1435 * <li><code>trueValue</code> and <code>falseValue</code>
1436 * are different strings.
1437 * </ul></dd></dl><dl>
1439 * @see nanoxml.XMLElement#setAttribute(java.lang.String, java.lang.Object)
1440 * setAttribute(String, Object)
1441 * @see nanoxml.XMLElement#removeAttribute(java.lang.String)
1442 * removeAttribute(String)
1443 * @see nanoxml.XMLElement#enumerateAttributeNames()
1445 public boolean getBooleanAttribute(String name,
1448 boolean defaultValue)
1450 if (this.ignoreCase) {
1451 name = name.toUpperCase();
1453 Object value = this.attributes.get(name);
1454 if (value == null) {
1455 return defaultValue;
1456 } else if (value.equals(trueValue)) {
1458 } else if (value.equals(falseValue)) {
1461 throw this.invalidValue(name, (String) value);
1467 * Returns an attribute by looking up a key in a hashtable.
1469 * @deprecated Use {@link #getIntAttribute(java.lang.String,
1470 * java.util.Hashtable, java.lang.String, boolean)
1471 * getIntAttribute} instead.
1473 public int getIntProperty(String name,
1477 return this.getIntAttribute(name, valueSet, defaultKey, false);
1482 * Returns an attribute.
1484 * @deprecated Use {@link #getStringAttribute(java.lang.String)
1485 * getStringAttribute} instead.
1487 public String getProperty(String name)
1489 return this.getStringAttribute(name);
1494 * Returns an attribute.
1496 * @deprecated Use {@link #getStringAttribute(java.lang.String,
1497 * java.lang.String) getStringAttribute} instead.
1499 public String getProperty(String name,
1500 String defaultValue)
1502 return this.getStringAttribute(name, defaultValue);
1507 * Returns an attribute.
1509 * @deprecated Use {@link #getIntAttribute(java.lang.String, int)
1510 * getIntAttribute} instead.
1512 public int getProperty(String name,
1515 return this.getIntAttribute(name, defaultValue);
1520 * Returns an attribute.
1522 * @deprecated Use {@link #getDoubleAttribute(java.lang.String, double)
1523 * getDoubleAttribute} instead.
1525 public double getProperty(String name,
1526 double defaultValue)
1528 return this.getDoubleAttribute(name, defaultValue);
1533 * Returns an attribute.
1535 * @deprecated Use {@link #getBooleanAttribute(java.lang.String,
1536 * java.lang.String, java.lang.String, boolean)
1537 * getBooleanAttribute} instead.
1539 public boolean getProperty(String key,
1542 boolean defaultValue)
1544 return this.getBooleanAttribute(key, trueValue, falseValue,
1550 * Returns an attribute by looking up a key in a hashtable.
1552 * @deprecated Use {@link #getAttribute(java.lang.String,
1553 * java.util.Hashtable, java.lang.String, boolean)
1554 * getAttribute} instead.
1556 public Object getProperty(String name,
1560 return this.getAttribute(name, valueSet, defaultKey, false);
1565 * Returns an attribute by looking up a key in a hashtable.
1567 * @deprecated Use {@link #getStringAttribute(java.lang.String,
1568 * java.util.Hashtable, java.lang.String, boolean)
1569 * getStringAttribute} instead.
1571 public String getStringProperty(String name,
1575 return this.getStringAttribute(name, valueSet, defaultKey, false);
1580 * Returns an attribute by looking up a key in a hashtable.
1582 * @deprecated Use {@link #getIntAttribute(java.lang.String,
1583 * java.util.Hashtable, java.lang.String, boolean)
1584 * getIntAttribute} instead.
1586 public int getSpecialIntProperty(String name,
1590 return this.getIntAttribute(name, valueSet, defaultKey, true);
1595 * Returns an attribute by looking up a key in a hashtable.
1597 * @deprecated Use {@link #getDoubleAttribute(java.lang.String,
1598 * java.util.Hashtable, java.lang.String, boolean)
1599 * getDoubleAttribute} instead.
1601 public double getSpecialDoubleProperty(String name,
1605 return this.getDoubleAttribute(name, valueSet, defaultKey, true);
1610 * Returns the name of the element.
1612 * @see nanoxml.XMLElement#setName(java.lang.String) setName(String)
1614 public String getName()
1621 * Returns the name of the element.
1623 * @deprecated Use {@link #getName() getName} instead.
1625 public String getTagName()
1627 return this.getName();
1632 * Reads one XML element from a java.io.Reader and parses it.
1635 * The reader from which to retrieve the XML data.
1637 * </dl><dl><dt><b>Preconditions:</b></dt><dd>
1638 * <ul><li><code>reader != null</code>
1639 * <li><code>reader</code> is not closed
1642 * <dl><dt><b>Postconditions:</b></dt><dd>
1643 * <ul><li>the state of the receiver is updated to reflect the XML element
1644 * parsed from the reader
1645 * <li>the reader points to the first character following the last
1646 * '>' character of the XML element
1647 * </ul></dd></dl><dl>
1649 * @throws java.io.IOException
1650 * If an error occured while reading the input.
1651 * @throws nanoxml.XMLParseException
1652 * If an error occured while parsing the read data.
1654 public void parseFromReader(Reader reader)
1655 throws IOException, XMLParseException
1657 this.parseFromReader(reader, /*startingLineNr*/ 1);
1662 * Reads one XML element from a java.io.Reader and parses it.
1665 * The reader from which to retrieve the XML data.
1666 * @param startingLineNr
1667 * The line number of the first line in the data.
1669 * </dl><dl><dt><b>Preconditions:</b></dt><dd>
1670 * <ul><li><code>reader != null</code>
1671 * <li><code>reader</code> is not closed
1674 * <dl><dt><b>Postconditions:</b></dt><dd>
1675 * <ul><li>the state of the receiver is updated to reflect the XML element
1676 * parsed from the reader
1677 * <li>the reader points to the first character following the last
1678 * '>' character of the XML element
1679 * </ul></dd></dl><dl>
1681 * @throws java.io.IOException
1682 * If an error occured while reading the input.
1683 * @throws nanoxml.XMLParseException
1684 * If an error occured while parsing the read data.
1686 public void parseFromReader(Reader reader,
1688 throws IOException, XMLParseException
1692 this.attributes = new Hashtable();
1693 this.children = new Vector();
1694 this.charReadTooMuch = '\0';
1695 this.reader = reader;
1696 this.parserLineNr = startingLineNr;
1699 char ch = this.scanWhitespace();
1702 throw this.expectedInput("<");
1705 ch = this.readChar();
1707 if ((ch == '!') || (ch == '?')) {
1708 this.skipSpecialTag(0);
1710 this.unreadChar(ch);
1711 this.scanElement(this);
1719 * Reads one XML element from a String and parses it.
1722 * The reader from which to retrieve the XML data.
1724 * </dl><dl><dt><b>Preconditions:</b></dt><dd>
1725 * <ul><li><code>string != null</code>
1726 * <li><code>string.length() > 0</code>
1729 * <dl><dt><b>Postconditions:</b></dt><dd>
1730 * <ul><li>the state of the receiver is updated to reflect the XML element
1731 * parsed from the reader
1732 * </ul></dd></dl><dl>
1734 * @throws nanoxml.XMLParseException
1735 * If an error occured while parsing the string.
1737 public void parseString(String string)
1738 throws XMLParseException
1741 this.parseFromReader(new StringReader(string),
1742 /*startingLineNr*/ 1);
1743 } catch (IOException e) {
1744 // Java exception handling suxx
1750 * Reads one XML element from a String and parses it.
1753 * The reader from which to retrieve the XML data.
1755 * The first character in <code>string</code> to scan.
1757 * </dl><dl><dt><b>Preconditions:</b></dt><dd>
1758 * <ul><li><code>string != null</code>
1759 * <li><code>offset < string.length()</code>
1760 * <li><code>offset >= 0</code>
1763 * <dl><dt><b>Postconditions:</b></dt><dd>
1764 * <ul><li>the state of the receiver is updated to reflect the XML element
1765 * parsed from the reader
1766 * </ul></dd></dl><dl>
1768 * @throws nanoxml.XMLParseException
1769 * If an error occured while parsing the string.
1771 public void parseString(String string,
1773 throws XMLParseException
1775 this.parseString(string.substring(offset));
1780 * Reads one XML element from a String and parses it.
1783 * The reader from which to retrieve the XML data.
1785 * The first character in <code>string</code> to scan.
1787 * The character where to stop scanning.
1788 * This character is not scanned.
1790 * </dl><dl><dt><b>Preconditions:</b></dt><dd>
1791 * <ul><li><code>string != null</code>
1792 * <li><code>end <= string.length()</code>
1793 * <li><code>offset < end</code>
1794 * <li><code>offset >= 0</code>
1797 * <dl><dt><b>Postconditions:</b></dt><dd>
1798 * <ul><li>the state of the receiver is updated to reflect the XML element
1799 * parsed from the reader
1800 * </ul></dd></dl><dl>
1802 * @throws nanoxml.XMLParseException
1803 * If an error occured while parsing the string.
1805 public void parseString(String string,
1808 throws XMLParseException
1810 this.parseString(string.substring(offset, end));
1815 * Reads one XML element from a String and parses it.
1818 * The reader from which to retrieve the XML data.
1820 * The first character in <code>string</code> to scan.
1822 * The character where to stop scanning.
1823 * This character is not scanned.
1824 * @param startingLineNr
1825 * The line number of the first line in the data.
1827 * </dl><dl><dt><b>Preconditions:</b></dt><dd>
1828 * <ul><li><code>string != null</code>
1829 * <li><code>end <= string.length()</code>
1830 * <li><code>offset < end</code>
1831 * <li><code>offset >= 0</code>
1834 * <dl><dt><b>Postconditions:</b></dt><dd>
1835 * <ul><li>the state of the receiver is updated to reflect the XML element
1836 * parsed from the reader
1837 * </ul></dd></dl><dl>
1839 * @throws nanoxml.XMLParseException
1840 * If an error occured while parsing the string.
1842 public void parseString(String string,
1846 throws XMLParseException
1848 string = string.substring(offset, end);
1850 this.parseFromReader(new StringReader(string), startingLineNr);
1851 } catch (IOException e) {
1852 // Java exception handling suxx
1858 * Reads one XML element from a char array and parses it.
1861 * The reader from which to retrieve the XML data.
1863 * The first character in <code>string</code> to scan.
1865 * The character where to stop scanning.
1866 * This character is not scanned.
1868 * </dl><dl><dt><b>Preconditions:</b></dt><dd>
1869 * <ul><li><code>input != null</code>
1870 * <li><code>end <= input.length</code>
1871 * <li><code>offset < end</code>
1872 * <li><code>offset >= 0</code>
1875 * <dl><dt><b>Postconditions:</b></dt><dd>
1876 * <ul><li>the state of the receiver is updated to reflect the XML element
1877 * parsed from the reader
1878 * </ul></dd></dl><dl>
1880 * @throws nanoxml.XMLParseException
1881 * If an error occured while parsing the string.
1883 public void parseCharArray(char[] input,
1886 throws XMLParseException
1888 this.parseCharArray(input, offset, end, /*startingLineNr*/ 1);
1893 * Reads one XML element from a char array and parses it.
1896 * The reader from which to retrieve the XML data.
1898 * The first character in <code>string</code> to scan.
1900 * The character where to stop scanning.
1901 * This character is not scanned.
1902 * @param startingLineNr
1903 * The line number of the first line in the data.
1905 * </dl><dl><dt><b>Preconditions:</b></dt><dd>
1906 * <ul><li><code>input != null</code>
1907 * <li><code>end <= input.length</code>
1908 * <li><code>offset < end</code>
1909 * <li><code>offset >= 0</code>
1912 * <dl><dt><b>Postconditions:</b></dt><dd>
1913 * <ul><li>the state of the receiver is updated to reflect the XML element
1914 * parsed from the reader
1915 * </ul></dd></dl><dl>
1917 * @throws nanoxml.XMLParseException
1918 * If an error occured while parsing the string.
1920 public void parseCharArray(char[] input,
1924 throws XMLParseException
1927 Reader reader = new CharArrayReader(input, offset, end);
1928 this.parseFromReader(reader, startingLineNr);
1929 } catch (IOException e) {
1930 // This exception will never happen.
1936 * Removes a child element.
1939 * The child element to remove.
1941 * </dl><dl><dt><b>Preconditions:</b></dt><dd>
1942 * <ul><li><code>child != null</code>
1943 * <li><code>child</code> is a child element of the receiver
1946 * <dl><dt><b>Postconditions:</b></dt><dd>
1947 * <ul><li>countChildren() => old.countChildren() - 1
1948 * <li>enumerateChildren() => old.enumerateChildren() - child
1949 * <li>getChildren() => old.enumerateChildren() - child
1950 * </ul></dd></dl><dl>
1952 * @see nanoxml.XMLElement#addChild(nanoxml.XMLElement)
1953 * addChild(XMLElement)
1954 * @see nanoxml.XMLElement#countChildren()
1955 * @see nanoxml.XMLElement#enumerateChildren()
1956 * @see nanoxml.XMLElement#getChildren()
1958 public void removeChild(XMLElement child)
1960 this.children.removeElement(child);
1965 * Removes an attribute.
1968 * The name of the attribute.
1970 * </dl><dl><dt><b>Preconditions:</b></dt><dd>
1971 * <ul><li><code>name != null</code>
1972 * <li><code>name</code> is a valid XML identifier
1975 * <dl><dt><b>Postconditions:</b></dt><dd>
1976 * <ul><li>enumerateAttributeNames()
1977 * => old.enumerateAttributeNames() - name
1978 * <li>getAttribute(name) => <code>null</code>
1979 * </ul></dd></dl><dl>
1981 * @see nanoxml.XMLElement#enumerateAttributeNames()
1982 * @see nanoxml.XMLElement#setDoubleAttribute(java.lang.String, double)
1983 * setDoubleAttribute(String, double)
1984 * @see nanoxml.XMLElement#setIntAttribute(java.lang.String, int)
1985 * setIntAttribute(String, int)
1986 * @see nanoxml.XMLElement#setAttribute(java.lang.String, java.lang.Object)
1987 * setAttribute(String, Object)
1988 * @see nanoxml.XMLElement#getAttribute(java.lang.String)
1989 * getAttribute(String)
1990 * @see nanoxml.XMLElement#getAttribute(java.lang.String, java.lang.Object)
1991 * getAttribute(String, Object)
1992 * @see nanoxml.XMLElement#getAttribute(java.lang.String,
1993 * java.util.Hashtable,
1994 * java.lang.String, boolean)
1995 * getAttribute(String, Hashtable, String, boolean)
1996 * @see nanoxml.XMLElement#getStringAttribute(java.lang.String)
1997 * getStringAttribute(String)
1998 * @see nanoxml.XMLElement#getStringAttribute(java.lang.String,
2000 * getStringAttribute(String, String)
2001 * @see nanoxml.XMLElement#getStringAttribute(java.lang.String,
2002 * java.util.Hashtable,
2003 * java.lang.String, boolean)
2004 * getStringAttribute(String, Hashtable, String, boolean)
2005 * @see nanoxml.XMLElement#getIntAttribute(java.lang.String)
2006 * getIntAttribute(String)
2007 * @see nanoxml.XMLElement#getIntAttribute(java.lang.String, int)
2008 * getIntAttribute(String, int)
2009 * @see nanoxml.XMLElement#getIntAttribute(java.lang.String,
2010 * java.util.Hashtable,
2011 * java.lang.String, boolean)
2012 * getIntAttribute(String, Hashtable, String, boolean)
2013 * @see nanoxml.XMLElement#getDoubleAttribute(java.lang.String)
2014 * getDoubleAttribute(String)
2015 * @see nanoxml.XMLElement#getDoubleAttribute(java.lang.String, double)
2016 * getDoubleAttribute(String, double)
2017 * @see nanoxml.XMLElement#getDoubleAttribute(java.lang.String,
2018 * java.util.Hashtable,
2019 * java.lang.String, boolean)
2020 * getDoubleAttribute(String, Hashtable, String, boolean)
2021 * @see nanoxml.XMLElement#getBooleanAttribute(java.lang.String,
2023 * java.lang.String, boolean)
2024 * getBooleanAttribute(String, String, String, boolean)
2026 public void removeAttribute(String name)
2028 if (this.ignoreCase) {
2029 name = name.toUpperCase();
2031 this.attributes.remove(name);
2036 * Removes an attribute.
2039 * The name of the attribute.
2041 * @deprecated Use {@link #removeAttribute(java.lang.String)
2042 * removeAttribute} instead.
2044 public void removeProperty(String name)
2046 this.removeAttribute(name);
2051 * Removes an attribute.
2054 * The name of the attribute.
2056 * @deprecated Use {@link #removeAttribute(java.lang.String)
2057 * removeAttribute} instead.
2059 public void removeChild(String name)
2061 this.removeAttribute(name);
2066 * Creates a new similar XML element.
2068 * You should override this method when subclassing XMLElement.
2070 protected XMLElement createAnotherElement()
2072 return new XMLElement(this.entities,
2073 this.ignoreWhitespace,
2080 * Changes the content string.
2083 * The new content string.
2085 public void setContent(String content)
2087 this.contents = content;
2092 * Changes the name of the element.
2097 * @deprecated Use {@link #setName(java.lang.String) setName} instead.
2099 public void setTagName(String name)
2106 * Changes the name of the element.
2111 * </dl><dl><dt><b>Preconditions:</b></dt><dd>
2112 * <ul><li><code>name != null</code>
2113 * <li><code>name</code> is a valid XML identifier
2116 * @see nanoxml.XMLElement#getName()
2118 public void setName(String name)
2125 * Writes the XML element to a string.
2127 * @see nanoxml.XMLElement#write(java.io.Writer) write(Writer)
2129 public String toString()
2132 ByteArrayOutputStream out = new ByteArrayOutputStream();
2133 OutputStreamWriter writer = new OutputStreamWriter(out);
2136 return new String(out.toByteArray());
2137 } catch (IOException e) {
2138 // Java exception handling suxx
2139 return super.toString();
2145 * Writes the XML element to a writer.
2148 * The writer to write the XML data to.
2150 * </dl><dl><dt><b>Preconditions:</b></dt><dd>
2151 * <ul><li><code>writer != null</code>
2152 * <li><code>writer</code> is not closed
2155 * @throws java.io.IOException
2156 * If the data could not be written to the writer.
2158 * @see nanoxml.XMLElement#toString()
2160 public void write(Writer writer)
2163 if (this.name == null) {
2164 this.writeEncoded(writer, this.contents);
2168 writer.write(this.name);
2169 if (! this.attributes.isEmpty()) {
2170 Enumeration enumV = this.attributes.keys();
2171 while (enumV.hasMoreElements()) {
2173 String key = (String) enumV.nextElement();
2174 String value = (String) this.attributes.get(key);
2176 writer.write('='); writer.write('"');
2177 this.writeEncoded(writer, value);
2181 if ((this.contents != null) && (this.contents.length() > 0)) {
2183 this.writeEncoded(writer, this.contents);
2184 writer.write('<'); writer.write('/');
2185 writer.write(this.name);
2187 } else if (this.children.isEmpty()) {
2188 writer.write('/'); writer.write('>');
2191 Enumeration enumV = this.enumerateChildren();
2192 while (enumV.hasMoreElements()) {
2193 XMLElement child = (XMLElement) enumV.nextElement();
2194 child.write(writer);
2196 writer.write('<'); writer.write('/');
2197 writer.write(this.name);
2204 * Writes a string encoded to a writer.
2207 * The writer to write the XML data to.
2209 * The string to write encoded.
2211 * </dl><dl><dt><b>Preconditions:</b></dt><dd>
2212 * <ul><li><code>writer != null</code>
2213 * <li><code>writer</code> is not closed
2214 * <li><code>str != null</code>
2217 protected void writeEncoded(Writer writer,
2221 for (int i = 0; i < str.length(); i += 1) {
2222 char ch = str.charAt(i);
2225 writer.write('&'); writer.write('l'); writer.write('t');
2229 writer.write('&'); writer.write('g'); writer.write('t');
2233 writer.write('&'); writer.write('a'); writer.write('m');
2234 writer.write('p'); writer.write(';');
2237 writer.write('&'); writer.write('q'); writer.write('u');
2238 writer.write('o'); writer.write('t'); writer.write(';');
2241 writer.write('&'); writer.write('a'); writer.write('p');
2242 writer.write('o'); writer.write('s'); writer.write(';');
2245 int unicode = (int) ch;
2246 if ((unicode < 32) || (unicode > 126)) {
2247 writer.write('&'); writer.write('#');
2249 writer.write(Integer.toString(unicode, 16));
2260 * Scans an identifier from the current reader.
2261 * The scanned identifier is appended to <code>result</code>.
2264 * The buffer in which the scanned identifier will be put.
2266 * </dl><dl><dt><b>Preconditions:</b></dt><dd>
2267 * <ul><li><code>result != null</code>
2268 * <li>The next character read from the reader is a valid first
2269 * character of an XML identifier.
2272 * <dl><dt><b>Postconditions:</b></dt><dd>
2273 * <ul><li>The next character read from the reader won't be an identifier
2275 * </ul></dd></dl><dl>
2277 protected void scanIdentifier(StringBuffer result)
2281 char ch = this.readChar();
2282 if (((ch < 'A') || (ch > 'Z')) && ((ch < 'a') || (ch > 'z'))
2283 && ((ch < '0') || (ch > '9')) && (ch != '_') && (ch != '.')
2284 && (ch != ':') && (ch != '-') && (ch <= '\u007E')) {
2285 this.unreadChar(ch);
2294 * This method scans an identifier from the current reader.
2296 * @return the next character following the whitespace.
2298 protected char scanWhitespace()
2302 char ch = this.readChar();
2317 * This method scans an identifier from the current reader.
2318 * The scanned whitespace is appended to <code>result</code>.
2320 * @return the next character following the whitespace.
2322 * </dl><dl><dt><b>Preconditions:</b></dt><dd>
2323 * <ul><li><code>result != null</code>
2326 protected char scanWhitespace(StringBuffer result)
2330 char ch = this.readChar();
2346 * This method scans a delimited string from the current reader.
2347 * The scanned string without delimiters is appended to
2348 * <code>string</code>.
2350 * </dl><dl><dt><b>Preconditions:</b></dt><dd>
2351 * <ul><li><code>string != null</code>
2352 * <li>the next char read is the string delimiter
2355 protected void scanString(StringBuffer string)
2358 char delimiter = this.readChar();
2359 if ((delimiter != '\'') && (delimiter != '"')) {
2360 throw this.expectedInput("' or \"");
2363 char ch = this.readChar();
2364 if (ch == delimiter) {
2366 } else if (ch == '&') {
2367 this.resolveEntity(string);
2376 * Scans a #PCDATA element. CDATA sections and entities are resolved.
2377 * The next < char is skipped.
2378 * The scanned data is appended to <code>data</code>.
2380 * </dl><dl><dt><b>Preconditions:</b></dt><dd>
2381 * <ul><li><code>data != null</code>
2384 protected void scanPCData(StringBuffer data)
2388 char ch = this.readChar();
2390 ch = this.readChar();
2392 this.checkCDATA(data);
2394 this.unreadChar(ch);
2397 } else if (ch == '&') {
2398 this.resolveEntity(data);
2407 * Scans a special tag and if the tag is a CDATA section, append its
2408 * content to <code>buf</code>.
2410 * </dl><dl><dt><b>Preconditions:</b></dt><dd>
2411 * <ul><li><code>buf != null</code>
2412 * <li>The first < has already been read.
2415 protected boolean checkCDATA(StringBuffer buf)
2418 char ch = this.readChar();
2420 this.unreadChar(ch);
2421 this.skipSpecialTag(0);
2423 } else if (! this.checkLiteral("CDATA[")) {
2424 this.skipSpecialTag(1); // one [ has already been read
2427 int delimiterCharsSkipped = 0;
2428 while (delimiterCharsSkipped < 3) {
2429 ch = this.readChar();
2432 if (delimiterCharsSkipped < 2) {
2433 delimiterCharsSkipped += 1;
2437 delimiterCharsSkipped = 0;
2441 if (delimiterCharsSkipped < 2) {
2442 for (int i = 0; i < delimiterCharsSkipped; i++) {
2445 delimiterCharsSkipped = 0;
2448 delimiterCharsSkipped = 3;
2452 for (int i = 0; i < delimiterCharsSkipped; i += 1) {
2456 delimiterCharsSkipped = 0;
2467 * </dl><dl><dt><b>Preconditions:</b></dt><dd>
2468 * <ul><li>The first <!-- has already been read.
2471 protected void skipComment()
2474 int dashesToRead = 2;
2475 while (dashesToRead > 0) {
2476 char ch = this.readChar();
2483 if (this.readChar() != '>') {
2484 throw this.expectedInput(">");
2490 * Skips a special tag or comment.
2492 * @param bracketLevel The number of open square brackets ([) that have
2493 * already been read.
2495 * </dl><dl><dt><b>Preconditions:</b></dt><dd>
2496 * <ul><li>The first <! has already been read.
2497 * <li><code>bracketLevel >= 0</code>
2500 protected void skipSpecialTag(int bracketLevel)
2503 int tagLevel = 1; // <
2504 char stringDelimiter = '\0';
2505 if (bracketLevel == 0) {
2506 char ch = this.readChar();
2509 } else if (ch == '-') {
2510 ch = this.readChar();
2513 } else if (ch == ']') {
2515 } else if (ch == '-') {
2521 while (tagLevel > 0) {
2522 char ch = this.readChar();
2523 if (stringDelimiter == '\0') {
2524 if ((ch == '"') || (ch == '\'')) {
2525 stringDelimiter = ch;
2526 } else if (bracketLevel <= 0) {
2529 } else if (ch == '>') {
2535 } else if (ch == ']') {
2539 if (ch == stringDelimiter) {
2540 stringDelimiter = '\0';
2548 * Scans the data for literal text.
2549 * Scanning stops when a character does not match or after the complete
2550 * text has been checked, whichever comes first.
2552 * @param literal the literal to check.
2554 * </dl><dl><dt><b>Preconditions:</b></dt><dd>
2555 * <ul><li><code>literal != null</code>
2558 protected boolean checkLiteral(String literal)
2561 int length = literal.length();
2562 for (int i = 0; i < length; i += 1) {
2563 if (this.readChar() != literal.charAt(i)) {
2572 * Reads a character from a reader.
2574 protected char readChar()
2577 if (this.charReadTooMuch != '\0') {
2578 char ch = this.charReadTooMuch;
2579 this.charReadTooMuch = '\0';
2582 int i = this.reader.read();
2584 throw this.unexpectedEndOfData();
2585 } else if (i == 10) {
2586 this.parserLineNr += 1;
2596 * Scans an XML element.
2598 * @param elt The element that will contain the result.
2600 * </dl><dl><dt><b>Preconditions:</b></dt><dd>
2601 * <ul><li>The first < has already been read.
2602 * <li><code>elt != null</code>
2605 protected void scanElement(XMLElement elt)
2608 StringBuffer buf = new StringBuffer();
2609 this.scanIdentifier(buf);
2610 String name = buf.toString();
2612 char ch = this.scanWhitespace();
2613 while ((ch != '>') && (ch != '/')) {
2615 this.unreadChar(ch);
2616 this.scanIdentifier(buf);
2617 String key = buf.toString();
2618 ch = this.scanWhitespace();
2620 throw this.expectedInput("=");
2622 this.unreadChar(this.scanWhitespace());
2624 this.scanString(buf);
2625 elt.setAttribute(key, buf);
2626 ch = this.scanWhitespace();
2629 ch = this.readChar();
2631 throw this.expectedInput(">");
2636 ch = this.scanWhitespace(buf);
2638 this.unreadChar(ch);
2639 this.scanPCData(buf);
2642 ch = this.readChar();
2644 if (this.checkCDATA(buf)) {
2645 this.scanPCData(buf);
2648 ch = this.scanWhitespace(buf);
2650 this.unreadChar(ch);
2651 this.scanPCData(buf);
2656 if ((ch != '/') || this.ignoreWhitespace) {
2660 this.unreadChar(ch);
2666 if (buf.length() == 0) {
2669 ch = this.readChar();
2671 throw this.expectedInput("Comment or Element");
2673 ch = this.readChar();
2675 throw this.expectedInput("Comment or Element");
2679 this.unreadChar(ch);
2680 XMLElement child = this.createAnotherElement();
2681 this.scanElement(child);
2682 elt.addChild(child);
2684 ch = this.scanWhitespace();
2686 throw this.expectedInput("<");
2688 ch = this.readChar();
2690 this.unreadChar(ch);
2692 if (this.ignoreWhitespace) {
2693 elt.setContent(buf.toString().trim());
2695 elt.setContent(buf.toString());
2698 ch = this.readChar();
2700 throw this.expectedInput("/");
2702 this.unreadChar(this.scanWhitespace());
2703 if (! this.checkLiteral(name)) {
2704 throw this.expectedInput(name);
2706 if (this.scanWhitespace() != '>') {
2707 throw this.expectedInput(">");
2713 * Resolves an entity. The name of the entity is read from the reader.
2714 * The value of the entity is appended to <code>buf</code>.
2716 * @param buf Where to put the entity value.
2718 * </dl><dl><dt><b>Preconditions:</b></dt><dd>
2719 * <ul><li>The first & has already been read.
2720 * <li><code>buf != null</code>
2723 protected void resolveEntity(StringBuffer buf)
2727 StringBuffer keyBuf = new StringBuffer();
2729 ch = this.readChar();
2735 String key = keyBuf.toString();
2736 if (key.charAt(0) == '#') {
2738 if (key.charAt(1) == 'x') {
2739 ch = (char) Integer.parseInt(key.substring(2), 16);
2741 ch = (char) Integer.parseInt(key.substring(1), 10);
2743 } catch (NumberFormatException e) {
2744 throw this.unknownEntity(key);
2748 char[] value = (char[]) this.entities.get(key);
2749 if (value == null) {
2750 throw this.unknownEntity(key);
2758 * Pushes a character back to the read-back buffer.
2760 * @param ch The character to push back.
2762 * </dl><dl><dt><b>Preconditions:</b></dt><dd>
2763 * <ul><li>The read-back buffer is empty.
2764 * <li><code>ch != '\0'</code>
2767 protected void unreadChar(char ch)
2769 this.charReadTooMuch = ch;
2774 * Creates a parse exception for when an invalid valueset is given to
2777 * @param name The name of the entity.
2779 * </dl><dl><dt><b>Preconditions:</b></dt><dd>
2780 * <ul><li><code>name != null</code>
2783 protected XMLParseException invalidValueSet(String name)
2785 String msg = "Invalid value set (entity name = \"" + name + "\")";
2786 return new XMLParseException(this.getName(), this.parserLineNr, msg);
2791 * Creates a parse exception for when an invalid value is given to a
2794 * @param name The name of the entity.
2795 * @param value The value of the entity.
2797 * </dl><dl><dt><b>Preconditions:</b></dt><dd>
2798 * <ul><li><code>name != null</code>
2799 * <li><code>value != null</code>
2802 protected XMLParseException invalidValue(String name,
2805 String msg = "Attribute \"" + name + "\" does not contain a valid "
2806 + "value (\"" + value + "\")";
2807 return new XMLParseException(this.getName(), this.parserLineNr, msg);
2812 * Creates a parse exception for when the end of the data input has been
2815 protected XMLParseException unexpectedEndOfData()
2817 String msg = "Unexpected end of data reached";
2818 return new XMLParseException(this.getName(), this.parserLineNr, msg);
2823 * Creates a parse exception for when a syntax error occured.
2825 * @param context The context in which the error occured.
2827 * </dl><dl><dt><b>Preconditions:</b></dt><dd>
2828 * <ul><li><code>context != null</code>
2829 * <li><code>context.length() > 0</code>
2832 protected XMLParseException syntaxError(String context)
2834 String msg = "Syntax error while parsing " + context;
2835 return new XMLParseException(this.getName(), this.parserLineNr, msg);
2840 * Creates a parse exception for when the next character read is not
2841 * the character that was expected.
2843 * @param charSet The set of characters (in human readable form) that was
2846 * </dl><dl><dt><b>Preconditions:</b></dt><dd>
2847 * <ul><li><code>charSet != null</code>
2848 * <li><code>charSet.length() > 0</code>
2851 protected XMLParseException expectedInput(String charSet)
2853 String msg = "Expected: " + charSet;
2854 return new XMLParseException(this.getName(), this.parserLineNr, msg);
2859 * Creates a parse exception for when an entity could not be resolved.
2861 * @param name The name of the entity.
2863 * </dl><dl><dt><b>Preconditions:</b></dt><dd>
2864 * <ul><li><code>name != null</code>
2865 * <li><code>name.length() > 0</code>
2868 protected XMLParseException unknownEntity(String name)
2870 String msg = "Unknown or invalid entity: &" + name + ";";
2871 return new XMLParseException(this.getName(), this.parserLineNr, msg);