4
* $Date: 2009-10-14 19:49:29 -0700 (Wed, 14 Oct 2009) $
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
*****************************************************************************/
30
package org.pushingpixels.lafplugin;
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 enum = element.getAttributeNames();<BR>
67
* while (enum.hasMoreElements()) {<BR>
68
* String key = (String) enum.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$, $Revision: 39 $
103
public class XMLElement
107
* Serialization serial version ID.
109
static final long serialVersionUID = 6685035139346394777L;
113
* Major version of NanoXML. Classes with the same major and minor
114
* version are binary compatible. Classes with the same major version
115
* are source compatible. If the major version is different, you may
116
* need to modify the client source code.
118
* see nanoxml.XMLElement#NANOXML_MINOR_VERSION
120
public static final int NANOXML_MAJOR_VERSION = 2;
124
* Minor version of NanoXML. Classes with the same major and minor
125
* version are binary compatible. Classes with the same major version
126
* are source compatible. If the major version is different, you may
127
* need to modify the client source code.
129
* see nanoxml.XMLElement#NANOXML_MAJOR_VERSION
131
public static final int NANOXML_MINOR_VERSION = 2;
135
* The attributes given to the element.
137
* <dl><dt><b>Invariants:</b></dt><dd>
138
* <ul><li>The field can be empty.
139
* <li>The field is never <code>null</code>.
140
* <li>The keys and the values are strings.
143
private Hashtable attributes;
147
* Child elements of the element.
149
* <dl><dt><b>Invariants:</b></dt><dd>
150
* <ul><li>The field can be empty.
151
* <li>The field is never <code>null</code>.
152
* <li>The elements are instances of <code>XMLElement</code>
153
* or a subclass of <code>XMLElement</code>.
156
private Vector children;
160
* The name of the element.
162
* <dl><dt><b>Invariants:</b></dt><dd>
163
* <ul><li>The field is <code>null</code> iff the element is not
164
* initialized by either parse or setName.
165
* <li>If the field is not <code>null</code>, it's not empty.
166
* <li>If the field is not <code>null</code>, it contains a valid
174
* The #PCDATA content of the object.
176
* <dl><dt><b>Invariants:</b></dt><dd>
177
* <ul><li>The field is <code>null</code> iff the element is not a
179
* <li>The field can be any string, including the empty string.
182
private String contents;
186
* Conversion table for &...; entities. The keys are the entity names
187
* without the & and ; delimiters.
189
* <dl><dt><b>Invariants:</b></dt><dd>
190
* <ul><li>The field is never <code>null</code>.
191
* <li>The field always contains the following associations:
192
* "lt" => "<", "gt" => ">",
193
* "quot" => "\"", "apos" => "'",
194
* "amp" => "&"
195
* <li>The keys are strings
196
* <li>The values are char arrays
199
private Hashtable entities;
203
* The line number where the element starts.
205
* <dl><dt><b>Invariants:</b></dt><dd>
206
* <ul><li><code>lineNr >= 0</code>
213
* <code>true</code> if the case of the element and attribute names
214
* are case insensitive.
216
private boolean ignoreCase;
220
* <code>true</code> if the leading and trailing whitespace of #PCDATA
221
* sections have to be ignored.
223
private boolean ignoreWhitespace;
227
* Character read too much.
228
* This character provides push-back functionality to the input reader
229
* without having to use a PushbackReader.
230
* If there is no such character, this field is '\0'.
232
private char charReadTooMuch;
236
* The reader provided by the caller of the parse method.
238
* <dl><dt><b>Invariants:</b></dt><dd>
239
* <ul><li>The field is not <code>null</code> while the parse method
243
private Reader reader;
247
* The current line number in the source content.
249
* <dl><dt><b>Invariants:</b></dt><dd>
250
* <ul><li>parserLineNr > 0 while the parse method is running.
253
private int parserLineNr;
257
* Creates and initializes a new XML element.
258
* Calling the construction is equivalent to:
259
* <ul><code>new XMLElement(new Hashtable(), false, true)
262
* <dl><dt><b>Postconditions:</b></dt><dd>
263
* <ul><li>countChildren() => 0
264
* <li>enumerateChildren() => empty enumeration
265
* <li>enumeratePropertyNames() => empty enumeration
266
* <li>getChildren() => empty vector
267
* <li>getContent() => ""
268
* <li>getLineNr() => 0
269
* <li>getName() => null
272
* see nanoxml.XMLElement#XMLElement(java.util.Hashtable)
273
* XMLElement(Hashtable)
274
* see nanoxml.XMLElement#XMLElement(boolean)
275
* see nanoxml.XMLElement#XMLElement(java.util.Hashtable,boolean)
276
* XMLElement(Hashtable, boolean)
280
this(new Hashtable(), false, true, true);
285
* Creates and initializes a new XML element.
286
* Calling the construction is equivalent to:
287
* <ul><code>new XMLElement(entities, false, true)
291
* The entity conversion table.
293
* </dl><dl><dt><b>Preconditions:</b></dt><dd>
294
* <ul><li><code>entities != null</code>
297
* <dl><dt><b>Postconditions:</b></dt><dd>
298
* <ul><li>countChildren() => 0
299
* <li>enumerateChildren() => empty enumeration
300
* <li>enumeratePropertyNames() => empty enumeration
301
* <li>getChildren() => empty vector
302
* <li>getContent() => ""
303
* <li>getLineNr() => 0
304
* <li>getName() => null
305
* </ul></dd></dl><dl>
307
* see nanoxml.XMLElement#XMLElement()
308
* see nanoxml.XMLElement#XMLElement(boolean)
309
* see nanoxml.XMLElement#XMLElement(java.util.Hashtable,boolean)
310
* XMLElement(Hashtable, boolean)
312
public XMLElement(Hashtable entities)
314
this(entities, false, true, true);
319
* Creates and initializes a new XML element.
320
* Calling the construction is equivalent to:
321
* <ul><code>new XMLElement(new Hashtable(), skipLeadingWhitespace, true)
324
* @param skipLeadingWhitespace
325
* <code>true</code> if leading and trailing whitespace in PCDATA
326
* content has to be removed.
328
* </dl><dl><dt><b>Postconditions:</b></dt><dd>
329
* <ul><li>countChildren() => 0
330
* <li>enumerateChildren() => empty enumeration
331
* <li>enumeratePropertyNames() => empty enumeration
332
* <li>getChildren() => empty vector
333
* <li>getContent() => ""
334
* <li>getLineNr() => 0
335
* <li>getName() => null
336
* </ul></dd></dl><dl>
338
* see nanoxml.XMLElement#XMLElement()
339
* see nanoxml.XMLElement#XMLElement(java.util.Hashtable)
340
* XMLElement(Hashtable)
341
* see nanoxml.XMLElement#XMLElement(java.util.Hashtable,boolean)
342
* XMLElement(Hashtable, boolean)
344
public XMLElement(boolean skipLeadingWhitespace)
346
this(new Hashtable(), skipLeadingWhitespace, true, true);
351
* Creates and initializes a new XML element.
352
* Calling the construction is equivalent to:
353
* <ul><code>new XMLElement(entities, skipLeadingWhitespace, true)
357
* The entity conversion table.
358
* @param skipLeadingWhitespace
359
* <code>true</code> if leading and trailing whitespace in PCDATA
360
* content has to be removed.
362
* </dl><dl><dt><b>Preconditions:</b></dt><dd>
363
* <ul><li><code>entities != null</code>
366
* <dl><dt><b>Postconditions:</b></dt><dd>
367
* <ul><li>countChildren() => 0
368
* <li>enumerateChildren() => empty enumeration
369
* <li>enumeratePropertyNames() => empty enumeration
370
* <li>getChildren() => empty vector
371
* <li>getContent() => ""
372
* <li>getLineNr() => 0
373
* <li>getName() => null
374
* </ul></dd></dl><dl>
376
* see nanoxml.XMLElement#XMLElement()
377
* see nanoxml.XMLElement#XMLElement(boolean)
378
* see nanoxml.XMLElement#XMLElement(java.util.Hashtable)
379
* XMLElement(Hashtable)
381
public XMLElement(Hashtable entities,
382
boolean skipLeadingWhitespace)
384
this(entities, skipLeadingWhitespace, true, true);
389
* Creates and initializes a new XML element.
392
* The entity conversion table.
393
* @param skipLeadingWhitespace
394
* <code>true</code> if leading and trailing whitespace in PCDATA
395
* content has to be removed.
397
* <code>true</code> if the case of element and attribute names have
400
* </dl><dl><dt><b>Preconditions:</b></dt><dd>
401
* <ul><li><code>entities != null</code>
404
* <dl><dt><b>Postconditions:</b></dt><dd>
405
* <ul><li>countChildren() => 0
406
* <li>enumerateChildren() => empty enumeration
407
* <li>enumeratePropertyNames() => empty enumeration
408
* <li>getChildren() => empty vector
409
* <li>getContent() => ""
410
* <li>getLineNr() => 0
411
* <li>getName() => null
412
* </ul></dd></dl><dl>
414
* see nanoxml.XMLElement#XMLElement()
415
* see nanoxml.XMLElement#XMLElement(boolean)
416
* see nanoxml.XMLElement#XMLElement(java.util.Hashtable)
417
* XMLElement(Hashtable)
418
* see nanoxml.XMLElement#XMLElement(java.util.Hashtable,boolean)
419
* XMLElement(Hashtable, boolean)
421
public XMLElement(Hashtable entities,
422
boolean skipLeadingWhitespace,
425
this(entities, skipLeadingWhitespace, true, ignoreCase);
430
* Creates and initializes a new XML element.
432
* This constructor should <I>only</I> be called from
433
* {@link #createAnotherElement() createAnotherElement}
434
* to create child elements.
437
* The entity conversion table.
438
* @param skipLeadingWhitespace
439
* <code>true</code> if leading and trailing whitespace in PCDATA
440
* content has to be removed.
441
* @param fillBasicConversionTable
442
* <code>true</code> if the basic entities need to be added to
445
* <code>true</code> if the case of element and attribute names have
448
* </dl><dl><dt><b>Preconditions:</b></dt><dd>
449
* <ul><li><code>entities != null</code>
450
* <li>if <code>fillBasicConversionTable == false</code>
451
* then <code>entities</code> contains at least the following
452
* entries: <code>amp</code>, <code>lt</code>, <code>gt</code>,
453
* <code>apos</code> and <code>quot</code>
456
* <dl><dt><b>Postconditions:</b></dt><dd>
457
* <ul><li>countChildren() => 0
458
* <li>enumerateChildren() => empty enumeration
459
* <li>enumeratePropertyNames() => empty enumeration
460
* <li>getChildren() => empty vector
461
* <li>getContent() => ""
462
* <li>getLineNr() => 0
463
* <li>getName() => null
464
* </ul></dd></dl><dl>
466
* see nanoxml.XMLElement#createAnotherElement()
468
protected XMLElement(Hashtable entities,
469
boolean skipLeadingWhitespace,
470
boolean fillBasicConversionTable,
473
this.ignoreWhitespace = skipLeadingWhitespace;
474
this.ignoreCase = ignoreCase;
477
this.attributes = new Hashtable();
478
this.children = new Vector();
479
this.entities = entities;
481
Enumeration enumeration = this.entities.keys();
482
while (enumeration.hasMoreElements()) {
483
Object key = enumeration.nextElement();
484
Object value = this.entities.get(key);
485
if (value instanceof String) {
486
value = ((String) value).toCharArray();
487
this.entities.put(key, value);
490
if (fillBasicConversionTable) {
491
this.entities.put("amp", new char[] { '&' });
492
this.entities.put("quot", new char[] { '"' });
493
this.entities.put("apos", new char[] { '\'' });
494
this.entities.put("lt", new char[] { '<' });
495
this.entities.put("gt", new char[] { '>' });
501
* Adds a child element.
504
* The child element to add.
506
* </dl><dl><dt><b>Preconditions:</b></dt><dd>
507
* <ul><li><code>child != null</code>
508
* <li><code>child.getName() != null</code>
509
* <li><code>child</code> does not have a parent element
512
* <dl><dt><b>Postconditions:</b></dt><dd>
513
* <ul><li>countChildren() => old.countChildren() + 1
514
* <li>enumerateChildren() => old.enumerateChildren() + child
515
* <li>getChildren() => old.enumerateChildren() + child
516
* </ul></dd></dl><dl>
518
* see nanoxml.XMLElement#countChildren()
519
* see nanoxml.XMLElement#enumerateChildren()
520
* see nanoxml.XMLElement#getChildren()
521
* see nanoxml.XMLElement#removeChild(nanoxml.XMLElement)
522
* removeChild(XMLElement)
524
public void addChild(XMLElement child)
526
this.children.addElement(child);
531
* Adds or modifies an attribute.
534
* The name of the attribute.
536
* The value of the attribute.
538
* </dl><dl><dt><b>Preconditions:</b></dt><dd>
539
* <ul><li><code>name != null</code>
540
* <li><code>name</code> is a valid XML identifier
541
* <li><code>value != null</code>
544
* <dl><dt><b>Postconditions:</b></dt><dd>
545
* <ul><li>enumerateAttributeNames()
546
* => old.enumerateAttributeNames() + name
547
* <li>getAttribute(name) => value
548
* </ul></dd></dl><dl>
550
* see nanoxml.XMLElement#setDoubleAttribute(java.lang.String, double)
551
* setDoubleAttribute(String, double)
552
* see nanoxml.XMLElement#setIntAttribute(java.lang.String, int)
553
* setIntAttribute(String, int)
554
* see nanoxml.XMLElement#enumerateAttributeNames()
555
* see nanoxml.XMLElement#getAttribute(java.lang.String)
556
* getAttribute(String)
557
* see nanoxml.XMLElement#getAttribute(java.lang.String, java.lang.Object)
558
* getAttribute(String, Object)
559
* see nanoxml.XMLElement#getAttribute(java.lang.String,
560
* java.util.Hashtable,
561
* java.lang.String, boolean)
562
* getAttribute(String, Hashtable, String, boolean)
563
* see nanoxml.XMLElement#getStringAttribute(java.lang.String)
564
* getStringAttribute(String)
565
* see nanoxml.XMLElement#getStringAttribute(java.lang.String,
567
* getStringAttribute(String, String)
568
* see nanoxml.XMLElement#getStringAttribute(java.lang.String,
569
* java.util.Hashtable,
570
* java.lang.String, boolean)
571
* getStringAttribute(String, Hashtable, String, boolean)
573
public void setAttribute(String name,
576
if (this.ignoreCase) {
577
name = name.toUpperCase();
579
this.attributes.put(name, value.toString());
584
* Adds or modifies an attribute.
587
* The name of the attribute.
589
* The value of the attribute.
591
* @deprecated Use {@link #setAttribute(java.lang.String, java.lang.Object)
592
* setAttribute} instead.
594
public void addProperty(String name,
597
this.setAttribute(name, value);
602
* Adds or modifies an attribute.
605
* The name of the attribute.
607
* The value of the attribute.
609
* </dl><dl><dt><b>Preconditions:</b></dt><dd>
610
* <ul><li><code>name != null</code>
611
* <li><code>name</code> is a valid XML identifier
614
* <dl><dt><b>Postconditions:</b></dt><dd>
615
* <ul><li>enumerateAttributeNames()
616
* => old.enumerateAttributeNames() + name
617
* <li>getIntAttribute(name) => value
618
* </ul></dd></dl><dl>
620
* see nanoxml.XMLElement#setDoubleAttribute(java.lang.String, double)
621
* setDoubleAttribute(String, double)
622
* see nanoxml.XMLElement#setAttribute(java.lang.String, java.lang.Object)
623
* setAttribute(String, Object)
624
* see nanoxml.XMLElement#removeAttribute(java.lang.String)
625
* removeAttribute(String)
626
* see nanoxml.XMLElement#enumerateAttributeNames()
627
* see nanoxml.XMLElement#getIntAttribute(java.lang.String)
628
* getIntAttribute(String)
629
* see nanoxml.XMLElement#getIntAttribute(java.lang.String, int)
630
* getIntAttribute(String, int)
631
* see nanoxml.XMLElement#getIntAttribute(java.lang.String,
632
* java.util.Hashtable,
633
* java.lang.String, boolean)
634
* getIntAttribute(String, Hashtable, String, boolean)
636
public void setIntAttribute(String name,
639
if (this.ignoreCase) {
640
name = name.toUpperCase();
642
this.attributes.put(name, Integer.toString(value));
647
* Adds or modifies an attribute.
650
* The name of the attribute.
652
* The value of the attribute.
654
* @deprecated Use {@link #setIntAttribute(java.lang.String, int)
655
* setIntAttribute} instead.
657
public void addProperty(String key,
660
this.setIntAttribute(key, value);
665
* Adds or modifies an attribute.
668
* The name of the attribute.
670
* The value of the attribute.
672
* </dl><dl><dt><b>Preconditions:</b></dt><dd>
673
* <ul><li><code>name != null</code>
674
* <li><code>name</code> is a valid XML identifier
677
* <dl><dt><b>Postconditions:</b></dt><dd>
678
* <ul><li>enumerateAttributeNames()
679
* => old.enumerateAttributeNames() + name
680
* <li>getDoubleAttribute(name) => value
681
* </ul></dd></dl><dl>
683
* see nanoxml.XMLElement#setIntAttribute(java.lang.String, int)
684
* setIntAttribute(String, int)
685
* see nanoxml.XMLElement#setAttribute(java.lang.String, java.lang.Object)
686
* setAttribute(String, Object)
687
* see nanoxml.XMLElement#removeAttribute(java.lang.String)
688
* removeAttribute(String)
689
* see nanoxml.XMLElement#enumerateAttributeNames()
690
* see nanoxml.XMLElement#getDoubleAttribute(java.lang.String)
691
* getDoubleAttribute(String)
692
* see nanoxml.XMLElement#getDoubleAttribute(java.lang.String, double)
693
* getDoubleAttribute(String, double)
694
* see nanoxml.XMLElement#getDoubleAttribute(java.lang.String,
695
* java.util.Hashtable,
696
* java.lang.String, boolean)
697
* getDoubleAttribute(String, Hashtable, String, boolean)
699
public void setDoubleAttribute(String name,
702
if (this.ignoreCase) {
703
name = name.toUpperCase();
705
this.attributes.put(name, Double.toString(value));
710
* Adds or modifies an attribute.
713
* The name of the attribute.
715
* The value of the attribute.
717
* @deprecated Use {@link #setDoubleAttribute(java.lang.String, double)
718
* setDoubleAttribute} instead.
720
public void addProperty(String name,
723
this.setDoubleAttribute(name, value);
728
* Returns the number of child elements of the element.
730
* <dl><dt><b>Postconditions:</b></dt><dd>
731
* <ul><li><code>result >= 0</code>
734
* see nanoxml.XMLElement#addChild(nanoxml.XMLElement)
735
* addChild(XMLElement)
736
* see nanoxml.XMLElement#enumerateChildren()
737
* see nanoxml.XMLElement#getChildren()
738
* see nanoxml.XMLElement#removeChild(nanoxml.XMLElement)
739
* removeChild(XMLElement)
741
public int countChildren()
743
return this.children.size();
748
* Enumerates the attribute names.
750
* <dl><dt><b>Postconditions:</b></dt><dd>
751
* <ul><li><code>result != null</code>
754
* see nanoxml.XMLElement#setDoubleAttribute(java.lang.String, double)
755
* setDoubleAttribute(String, double)
756
* see nanoxml.XMLElement#setIntAttribute(java.lang.String, int)
757
* setIntAttribute(String, int)
758
* see nanoxml.XMLElement#setAttribute(java.lang.String, java.lang.Object)
759
* setAttribute(String, Object)
760
* see nanoxml.XMLElement#removeAttribute(java.lang.String)
761
* removeAttribute(String)
762
* see nanoxml.XMLElement#getAttribute(java.lang.String)
763
* getAttribute(String)
764
* see nanoxml.XMLElement#getAttribute(java.lang.String, java.lang.Object)
765
* getAttribute(String, String)
766
* see nanoxml.XMLElement#getAttribute(java.lang.String,
767
* java.util.Hashtable,
768
* java.lang.String, boolean)
769
* getAttribute(String, Hashtable, String, boolean)
770
* see nanoxml.XMLElement#getStringAttribute(java.lang.String)
771
* getStringAttribute(String)
772
* see nanoxml.XMLElement#getStringAttribute(java.lang.String,
774
* getStringAttribute(String, String)
775
* see nanoxml.XMLElement#getStringAttribute(java.lang.String,
776
* java.util.Hashtable,
777
* java.lang.String, boolean)
778
* getStringAttribute(String, Hashtable, String, boolean)
779
* see nanoxml.XMLElement#getIntAttribute(java.lang.String)
780
* getIntAttribute(String)
781
* see nanoxml.XMLElement#getIntAttribute(java.lang.String, int)
782
* getIntAttribute(String, int)
783
* see nanoxml.XMLElement#getIntAttribute(java.lang.String,
784
* java.util.Hashtable,
785
* java.lang.String, boolean)
786
* getIntAttribute(String, Hashtable, String, boolean)
787
* see nanoxml.XMLElement#getDoubleAttribute(java.lang.String)
788
* getDoubleAttribute(String)
789
* see nanoxml.XMLElement#getDoubleAttribute(java.lang.String, double)
790
* getDoubleAttribute(String, double)
791
* see nanoxml.XMLElement#getDoubleAttribute(java.lang.String,
792
* java.util.Hashtable,
793
* java.lang.String, boolean)
794
* getDoubleAttribute(String, Hashtable, String, boolean)
795
* see nanoxml.XMLElement#getBooleanAttribute(java.lang.String,
797
* java.lang.String, boolean)
798
* getBooleanAttribute(String, String, String, boolean)
800
public Enumeration enumerateAttributeNames()
802
return this.attributes.keys();
807
* Enumerates the attribute names.
809
* @deprecated Use {@link #enumerateAttributeNames()
810
* enumerateAttributeNames} instead.
812
public Enumeration enumeratePropertyNames()
814
return this.enumerateAttributeNames();
819
* Enumerates the child elements.
821
* <dl><dt><b>Postconditions:</b></dt><dd>
822
* <ul><li><code>result != null</code>
825
* see nanoxml.XMLElement#addChild(nanoxml.XMLElement)
826
* addChild(XMLElement)
827
* see nanoxml.XMLElement#countChildren()
828
* see nanoxml.XMLElement#getChildren()
829
* see nanoxml.XMLElement#removeChild(nanoxml.XMLElement)
830
* removeChild(XMLElement)
832
public Enumeration enumerateChildren()
834
return this.children.elements();
839
* Returns the child elements as a Vector. It is safe to modify this
842
* <dl><dt><b>Postconditions:</b></dt><dd>
843
* <ul><li><code>result != null</code>
846
* see nanoxml.XMLElement#addChild(nanoxml.XMLElement)
847
* addChild(XMLElement)
848
* see nanoxml.XMLElement#countChildren()
849
* see nanoxml.XMLElement#enumerateChildren()
850
* see nanoxml.XMLElement#removeChild(nanoxml.XMLElement)
851
* removeChild(XMLElement)
853
public Vector getChildren()
856
return (Vector) this.children.clone();
857
} catch (Exception e) {
858
// this never happens, however, some Java compilers are so
859
// braindead that they require this exception clause
866
* Returns the PCDATA content of the object. If there is no such content,
867
* <CODE>null</CODE> is returned.
869
* @deprecated Use {@link #getContent() getContent} instead.
871
public String getContents()
873
return this.getContent();
878
* Returns the PCDATA content of the object. If there is no such content,
879
* <CODE>null</CODE> is returned.
881
* see nanoxml.XMLElement#setContent(java.lang.String)
884
public String getContent()
886
return this.contents;
891
* Returns the line nr in the source data on which the element is found.
892
* This method returns <code>0</code> there is no associated source data.
894
* <dl><dt><b>Postconditions:</b></dt><dd>
895
* <ul><li><code>result >= 0</code>
898
public int getLineNr()
905
* Returns an attribute of the element.
906
* If the attribute doesn't exist, <code>null</code> is returned.
908
* @param name The name of the attribute.
910
* </dl><dl><dt><b>Preconditions:</b></dt><dd>
911
* <ul><li><code>name != null</code>
912
* <li><code>name</code> is a valid XML identifier
913
* </ul></dd></dl><dl>
915
* see nanoxml.XMLElement#setAttribute(java.lang.String, java.lang.Object)
916
* setAttribute(String, Object)
917
* see nanoxml.XMLElement#removeAttribute(java.lang.String)
918
* removeAttribute(String)
919
* see nanoxml.XMLElement#enumerateAttributeNames()
920
* see nanoxml.XMLElement#getAttribute(java.lang.String, java.lang.Object)
921
* getAttribute(String, Object)
922
* see nanoxml.XMLElement#getAttribute(java.lang.String,
923
* java.util.Hashtable,
924
* java.lang.String, boolean)
925
* getAttribute(String, Hashtable, String, boolean)
927
public Object getAttribute(String name)
929
return this.getAttribute(name, null);
934
* Returns an attribute of the element.
935
* If the attribute doesn't exist, <code>defaultValue</code> is returned.
937
* @param name The name of the attribute.
938
* @param defaultValue Key to use if the attribute is missing.
940
* </dl><dl><dt><b>Preconditions:</b></dt><dd>
941
* <ul><li><code>name != null</code>
942
* <li><code>name</code> is a valid XML identifier
943
* </ul></dd></dl><dl>
945
* see nanoxml.XMLElement#setAttribute(java.lang.String, java.lang.Object)
946
* setAttribute(String, Object)
947
* see nanoxml.XMLElement#removeAttribute(java.lang.String)
948
* removeAttribute(String)
949
* see nanoxml.XMLElement#enumerateAttributeNames()
950
* see nanoxml.XMLElement#getAttribute(java.lang.String)
951
* getAttribute(String)
952
* see nanoxml.XMLElement#getAttribute(java.lang.String,
953
* java.util.Hashtable,
954
* java.lang.String, boolean)
955
* getAttribute(String, Hashtable, String, boolean)
957
public Object getAttribute(String name,
960
if (this.ignoreCase) {
961
name = name.toUpperCase();
963
Object value = this.attributes.get(name);
965
value = defaultValue;
972
* Returns an attribute by looking up a key in a hashtable.
973
* If the attribute doesn't exist, the value corresponding to defaultKey
976
* As an example, if valueSet contains the mapping <code>"one" =>
978
* and the element contains the attribute <code>attr="one"</code>, then
979
* <code>getAttribute("attr", mapping, defaultKey, false)</code> returns
983
* The name of the attribute.
985
* Hashtable mapping keys to values.
987
* Key to use if the attribute is missing.
988
* @param allowLiterals
989
* <code>true</code> if literals are valid.
991
* </dl><dl><dt><b>Preconditions:</b></dt><dd>
992
* <ul><li><code>name != null</code>
993
* <li><code>name</code> is a valid XML identifier
994
* <li><code>valueSet</code> != null
995
* <li>the keys of <code>valueSet</code> are strings
996
* </ul></dd></dl><dl>
998
* see nanoxml.XMLElement#setAttribute(java.lang.String, java.lang.Object)
999
* setAttribute(String, Object)
1000
* see nanoxml.XMLElement#removeAttribute(java.lang.String)
1001
* removeAttribute(String)
1002
* see nanoxml.XMLElement#enumerateAttributeNames()
1003
* see nanoxml.XMLElement#getAttribute(java.lang.String)
1004
* getAttribute(String)
1005
* see nanoxml.XMLElement#getAttribute(java.lang.String, java.lang.Object)
1006
* getAttribute(String, Object)
1008
public Object getAttribute(String name,
1011
boolean allowLiterals)
1013
if (this.ignoreCase) {
1014
name = name.toUpperCase();
1016
Object key = this.attributes.get(name);
1021
result = valueSet.get(key);
1022
if (result == null) {
1023
if (allowLiterals) {
1026
throw this.invalidValue(name, (String) key);
1034
* Returns an attribute of the element.
1035
* If the attribute doesn't exist, <code>null</code> is returned.
1037
* @param name The name of the attribute.
1039
* </dl><dl><dt><b>Preconditions:</b></dt><dd>
1040
* <ul><li><code>name != null</code>
1041
* <li><code>name</code> is a valid XML identifier
1042
* </ul></dd></dl><dl>
1044
* see nanoxml.XMLElement#setAttribute(java.lang.String, java.lang.Object)
1045
* setAttribute(String, Object)
1046
* see nanoxml.XMLElement#removeAttribute(java.lang.String)
1047
* removeAttribute(String)
1048
* see nanoxml.XMLElement#enumerateAttributeNames()
1049
* see nanoxml.XMLElement#getStringAttribute(java.lang.String,
1051
* getStringAttribute(String, String)
1052
* see nanoxml.XMLElement#getStringAttribute(java.lang.String,
1053
* java.util.Hashtable,
1054
* java.lang.String, boolean)
1055
* getStringAttribute(String, Hashtable, String, boolean)
1057
public String getStringAttribute(String name)
1059
return this.getStringAttribute(name, null);
1064
* Returns an attribute of the element.
1065
* If the attribute doesn't exist, <code>defaultValue</code> is returned.
1067
* @param name The name of the attribute.
1068
* @param defaultValue Key to use if the attribute is missing.
1070
* </dl><dl><dt><b>Preconditions:</b></dt><dd>
1071
* <ul><li><code>name != null</code>
1072
* <li><code>name</code> is a valid XML identifier
1073
* </ul></dd></dl><dl>
1075
* see nanoxml.XMLElement#setAttribute(java.lang.String, java.lang.Object)
1076
* setAttribute(String, Object)
1077
* see nanoxml.XMLElement#removeAttribute(java.lang.String)
1078
* removeAttribute(String)
1079
* see nanoxml.XMLElement#enumerateAttributeNames()
1080
* see nanoxml.XMLElement#getStringAttribute(java.lang.String)
1081
* getStringAttribute(String)
1082
* see nanoxml.XMLElement#getStringAttribute(java.lang.String,
1083
* java.util.Hashtable,
1084
* java.lang.String, boolean)
1085
* getStringAttribute(String, Hashtable, String, boolean)
1087
public String getStringAttribute(String name,
1088
String defaultValue)
1090
return (String) this.getAttribute(name, defaultValue);
1095
* Returns an attribute by looking up a key in a hashtable.
1096
* If the attribute doesn't exist, the value corresponding to defaultKey
1099
* As an example, if valueSet contains the mapping <code>"one" =>
1101
* and the element contains the attribute <code>attr="one"</code>, then
1102
* <code>getAttribute("attr", mapping, defaultKey, false)</code> returns
1106
* The name of the attribute.
1108
* Hashtable mapping keys to values.
1110
* Key to use if the attribute is missing.
1111
* @param allowLiterals
1112
* <code>true</code> if literals are valid.
1114
* </dl><dl><dt><b>Preconditions:</b></dt><dd>
1115
* <ul><li><code>name != null</code>
1116
* <li><code>name</code> is a valid XML identifier
1117
* <li><code>valueSet</code> != null
1118
* <li>the keys of <code>valueSet</code> are strings
1119
* <li>the values of <code>valueSet</code> are strings
1120
* </ul></dd></dl><dl>
1122
* see nanoxml.XMLElement#setAttribute(java.lang.String, java.lang.Object)
1123
* setAttribute(String, Object)
1124
* see nanoxml.XMLElement#removeAttribute(java.lang.String)
1125
* removeAttribute(String)
1126
* see nanoxml.XMLElement#enumerateAttributeNames()
1127
* see nanoxml.XMLElement#getStringAttribute(java.lang.String)
1128
* getStringAttribute(String)
1129
* see nanoxml.XMLElement#getStringAttribute(java.lang.String,
1131
* getStringAttribute(String, String)
1133
public String getStringAttribute(String name,
1136
boolean allowLiterals)
1138
return (String) this.getAttribute(name, valueSet, defaultKey,
1144
* Returns an attribute of the element.
1145
* If the attribute doesn't exist, <code>0</code> is returned.
1147
* @param name The name of the attribute.
1149
* </dl><dl><dt><b>Preconditions:</b></dt><dd>
1150
* <ul><li><code>name != null</code>
1151
* <li><code>name</code> is a valid XML identifier
1152
* </ul></dd></dl><dl>
1154
* see nanoxml.XMLElement#setIntAttribute(java.lang.String, int)
1155
* setIntAttribute(String, int)
1156
* see nanoxml.XMLElement#enumerateAttributeNames()
1157
* see nanoxml.XMLElement#getIntAttribute(java.lang.String, int)
1158
* getIntAttribute(String, int)
1159
* see nanoxml.XMLElement#getIntAttribute(java.lang.String,
1160
* java.util.Hashtable,
1161
* java.lang.String, boolean)
1162
* getIntAttribute(String, Hashtable, String, boolean)
1164
public int getIntAttribute(String name)
1166
return this.getIntAttribute(name, 0);
1171
* Returns an attribute of the element.
1172
* If the attribute doesn't exist, <code>defaultValue</code> is returned.
1174
* @param name The name of the attribute.
1175
* @param defaultValue Key to use if the attribute is missing.
1177
* </dl><dl><dt><b>Preconditions:</b></dt><dd>
1178
* <ul><li><code>name != null</code>
1179
* <li><code>name</code> is a valid XML identifier
1180
* </ul></dd></dl><dl>
1182
* see nanoxml.XMLElement#setIntAttribute(java.lang.String, int)
1183
* setIntAttribute(String, int)
1184
* see nanoxml.XMLElement#enumerateAttributeNames()
1185
* see nanoxml.XMLElement#getIntAttribute(java.lang.String)
1186
* getIntAttribute(String)
1187
* see nanoxml.XMLElement#getIntAttribute(java.lang.String,
1188
* java.util.Hashtable,
1189
* java.lang.String, boolean)
1190
* getIntAttribute(String, Hashtable, String, boolean)
1192
public int getIntAttribute(String name,
1195
if (this.ignoreCase) {
1196
name = name.toUpperCase();
1198
String value = (String) this.attributes.get(name);
1199
if (value == null) {
1200
return defaultValue;
1203
return Integer.parseInt(value);
1204
} catch (NumberFormatException e) {
1205
throw this.invalidValue(name, value);
1212
* Returns an attribute by looking up a key in a hashtable.
1213
* If the attribute doesn't exist, the value corresponding to defaultKey
1216
* As an example, if valueSet contains the mapping <code>"one" => 1</code>
1217
* and the element contains the attribute <code>attr="one"</code>, then
1218
* <code>getIntAttribute("attr", mapping, defaultKey, false)</code> returns
1222
* The name of the attribute.
1224
* Hashtable mapping keys to values.
1226
* Key to use if the attribute is missing.
1227
* @param allowLiteralNumbers
1228
* <code>true</code> if literal numbers are valid.
1230
* </dl><dl><dt><b>Preconditions:</b></dt><dd>
1231
* <ul><li><code>name != null</code>
1232
* <li><code>name</code> is a valid XML identifier
1233
* <li><code>valueSet</code> != null
1234
* <li>the keys of <code>valueSet</code> are strings
1235
* <li>the values of <code>valueSet</code> are Integer objects
1236
* <li><code>defaultKey</code> is either <code>null</code>, a
1237
* key in <code>valueSet</code> or an integer.
1238
* </ul></dd></dl><dl>
1240
* see nanoxml.XMLElement#setIntAttribute(java.lang.String, int)
1241
* setIntAttribute(String, int)
1242
* see nanoxml.XMLElement#enumerateAttributeNames()
1243
* see nanoxml.XMLElement#getIntAttribute(java.lang.String)
1244
* getIntAttribute(String)
1245
* see nanoxml.XMLElement#getIntAttribute(java.lang.String, int)
1246
* getIntAttribute(String, int)
1248
public int getIntAttribute(String name,
1251
boolean allowLiteralNumbers)
1253
if (this.ignoreCase) {
1254
name = name.toUpperCase();
1256
Object key = this.attributes.get(name);
1262
result = (Integer) valueSet.get(key);
1263
} catch (ClassCastException e) {
1264
throw this.invalidValueSet(name);
1266
if (result == null) {
1267
if (! allowLiteralNumbers) {
1268
throw this.invalidValue(name, (String) key);
1271
result = Integer.valueOf((String) key);
1272
} catch (NumberFormatException e) {
1273
throw this.invalidValue(name, (String) key);
1281
* Returns an attribute of the element.
1282
* If the attribute doesn't exist, <code>0.0</code> is returned.
1284
* @param name The name of the attribute.
1286
* </dl><dl><dt><b>Preconditions:</b></dt><dd>
1287
* <ul><li><code>name != null</code>
1288
* <li><code>name</code> is a valid XML identifier
1289
* </ul></dd></dl><dl>
1291
* see nanoxml.XMLElement#setDoubleAttribute(java.lang.String, double)
1292
* setDoubleAttribute(String, double)
1293
* see nanoxml.XMLElement#enumerateAttributeNames()
1294
* see nanoxml.XMLElement#getDoubleAttribute(java.lang.String, double)
1295
* getDoubleAttribute(String, double)
1296
* see nanoxml.XMLElement#getDoubleAttribute(java.lang.String,
1297
* java.util.Hashtable,
1298
* java.lang.String, boolean)
1299
* getDoubleAttribute(String, Hashtable, String, boolean)
1301
public double getDoubleAttribute(String name)
1303
return this.getDoubleAttribute(name, 0.);
1308
* Returns an attribute of the element.
1309
* If the attribute doesn't exist, <code>defaultValue</code> is returned.
1311
* @param name The name of the attribute.
1312
* @param defaultValue Key to use if the attribute is missing.
1314
* </dl><dl><dt><b>Preconditions:</b></dt><dd>
1315
* <ul><li><code>name != null</code>
1316
* <li><code>name</code> is a valid XML identifier
1317
* </ul></dd></dl><dl>
1319
* see nanoxml.XMLElement#setDoubleAttribute(java.lang.String, double)
1320
* setDoubleAttribute(String, double)
1321
* see nanoxml.XMLElement#enumerateAttributeNames()
1322
* see nanoxml.XMLElement#getDoubleAttribute(java.lang.String)
1323
* getDoubleAttribute(String)
1324
* see nanoxml.XMLElement#getDoubleAttribute(java.lang.String,
1325
* java.util.Hashtable,
1326
* java.lang.String, boolean)
1327
* getDoubleAttribute(String, Hashtable, String, boolean)
1329
public double getDoubleAttribute(String name,
1330
double defaultValue)
1332
if (this.ignoreCase) {
1333
name = name.toUpperCase();
1335
String value = (String) this.attributes.get(name);
1336
if (value == null) {
1337
return defaultValue;
1340
return Double.valueOf(value);
1341
} catch (NumberFormatException e) {
1342
throw this.invalidValue(name, value);
1349
* Returns an attribute by looking up a key in a hashtable.
1350
* If the attribute doesn't exist, the value corresponding to defaultKey
1353
* As an example, if valueSet contains the mapping <code>"one" =>
1355
* and the element contains the attribute <code>attr="one"</code>, then
1356
* <code>getDoubleAttribute("attr", mapping, defaultKey, false)</code>
1357
* returns <code>1.0</code>.
1360
* The name of the attribute.
1362
* Hashtable mapping keys to values.
1364
* Key to use if the attribute is missing.
1365
* @param allowLiteralNumbers
1366
* <code>true</code> if literal numbers are valid.
1368
* </dl><dl><dt><b>Preconditions:</b></dt><dd>
1369
* <ul><li><code>name != null</code>
1370
* <li><code>name</code> is a valid XML identifier
1371
* <li><code>valueSet != null</code>
1372
* <li>the keys of <code>valueSet</code> are strings
1373
* <li>the values of <code>valueSet</code> are Double objects
1374
* <li><code>defaultKey</code> is either <code>null</code>, a
1375
* key in <code>valueSet</code> or a double.
1376
* </ul></dd></dl><dl>
1378
* see nanoxml.XMLElement#setDoubleAttribute(java.lang.String, double)
1379
* setDoubleAttribute(String, double)
1380
* see nanoxml.XMLElement#enumerateAttributeNames()
1381
* see nanoxml.XMLElement#getDoubleAttribute(java.lang.String)
1382
* getDoubleAttribute(String)
1383
* see nanoxml.XMLElement#getDoubleAttribute(java.lang.String, double)
1384
* getDoubleAttribute(String, double)
1386
public double getDoubleAttribute(String name,
1389
boolean allowLiteralNumbers)
1391
if (this.ignoreCase) {
1392
name = name.toUpperCase();
1394
Object key = this.attributes.get(name);
1400
result = (Double) valueSet.get(key);
1401
} catch (ClassCastException e) {
1402
throw this.invalidValueSet(name);
1404
if (result == null) {
1405
if (! allowLiteralNumbers) {
1406
throw this.invalidValue(name, (String) key);
1409
result = Double.valueOf((String) key);
1410
} catch (NumberFormatException e) {
1411
throw this.invalidValue(name, (String) key);
1419
* Returns an attribute of the element.
1420
* If the attribute doesn't exist, <code>defaultValue</code> is returned.
1421
* If the value of the attribute is equal to <code>trueValue</code>,
1422
* <code>true</code> is returned.
1423
* If the value of the attribute is equal to <code>falseValue</code>,
1424
* <code>false</code> is returned.
1425
* If the value doesn't match <code>trueValue</code> or
1426
* <code>falseValue</code>, an exception is thrown.
1428
* @param name The name of the attribute.
1429
* @param trueValue The value associated with <code>true</code>.
1430
* @param falseValue The value associated with <code>true</code>.
1431
* @param defaultValue Value to use if the attribute is missing.
1433
* </dl><dl><dt><b>Preconditions:</b></dt><dd>
1434
* <ul><li><code>name != null</code>
1435
* <li><code>name</code> is a valid XML identifier
1436
* <li><code>trueValue</code> and <code>falseValue</code>
1437
* are different strings.
1438
* </ul></dd></dl><dl>
1440
* see nanoxml.XMLElement#setAttribute(java.lang.String, java.lang.Object)
1441
* setAttribute(String, Object)
1442
* see nanoxml.XMLElement#removeAttribute(java.lang.String)
1443
* removeAttribute(String)
1444
* see nanoxml.XMLElement#enumerateAttributeNames()
1446
public boolean getBooleanAttribute(String name,
1449
boolean defaultValue)
1451
if (this.ignoreCase) {
1452
name = name.toUpperCase();
1454
Object value = this.attributes.get(name);
1455
if (value == null) {
1456
return defaultValue;
1457
} else if (value.equals(trueValue)) {
1459
} else if (value.equals(falseValue)) {
1462
throw this.invalidValue(name, (String) value);
1468
* Returns an attribute by looking up a key in a hashtable.
1470
* @deprecated Use {@link #getIntAttribute(java.lang.String,
1471
* java.util.Hashtable, java.lang.String, boolean)
1472
* getIntAttribute} instead.
1474
public int getIntProperty(String name,
1478
return this.getIntAttribute(name, valueSet, defaultKey, false);
1483
* Returns an attribute.
1485
* @deprecated Use {@link #getStringAttribute(java.lang.String)
1486
* getStringAttribute} instead.
1488
public String getProperty(String name)
1490
return this.getStringAttribute(name);
1495
* Returns an attribute.
1497
* @deprecated Use {@link #getStringAttribute(java.lang.String,
1498
* java.lang.String) getStringAttribute} instead.
1500
public String getProperty(String name,
1501
String defaultValue)
1503
return this.getStringAttribute(name, defaultValue);
1508
* Returns an attribute.
1510
* @deprecated Use {@link #getIntAttribute(java.lang.String, int)
1511
* getIntAttribute} instead.
1513
public int getProperty(String name,
1516
return this.getIntAttribute(name, defaultValue);
1521
* Returns an attribute.
1523
* @deprecated Use {@link #getDoubleAttribute(java.lang.String, double)
1524
* getDoubleAttribute} instead.
1526
public double getProperty(String name,
1527
double defaultValue)
1529
return this.getDoubleAttribute(name, defaultValue);
1534
* Returns an attribute.
1536
* @deprecated Use {@link #getBooleanAttribute(java.lang.String,
1537
* java.lang.String, java.lang.String, boolean)
1538
* getBooleanAttribute} instead.
1540
public boolean getProperty(String key,
1543
boolean defaultValue)
1545
return this.getBooleanAttribute(key, trueValue, falseValue,
1551
* Returns an attribute by looking up a key in a hashtable.
1553
* @deprecated Use {@link #getAttribute(java.lang.String,
1554
* java.util.Hashtable, java.lang.String, boolean)
1555
* getAttribute} instead.
1557
public Object getProperty(String name,
1561
return this.getAttribute(name, valueSet, defaultKey, false);
1566
* Returns an attribute by looking up a key in a hashtable.
1568
* @deprecated Use {@link #getStringAttribute(java.lang.String,
1569
* java.util.Hashtable, java.lang.String, boolean)
1570
* getStringAttribute} instead.
1572
public String getStringProperty(String name,
1576
return this.getStringAttribute(name, valueSet, defaultKey, false);
1581
* Returns an attribute by looking up a key in a hashtable.
1583
* @deprecated Use {@link #getIntAttribute(java.lang.String,
1584
* java.util.Hashtable, java.lang.String, boolean)
1585
* getIntAttribute} instead.
1587
public int getSpecialIntProperty(String name,
1591
return this.getIntAttribute(name, valueSet, defaultKey, true);
1596
* Returns an attribute by looking up a key in a hashtable.
1598
* @deprecated Use {@link #getDoubleAttribute(java.lang.String,
1599
* java.util.Hashtable, java.lang.String, boolean)
1600
* getDoubleAttribute} instead.
1602
public double getSpecialDoubleProperty(String name,
1606
return this.getDoubleAttribute(name, valueSet, defaultKey, true);
1611
* Returns the name of the element.
1613
* see nanoxml.XMLElement#setName(java.lang.String) setName(String)
1615
public String getName()
1622
* Returns the name of the element.
1624
* @deprecated Use {@link #getName() getName} instead.
1626
public String getTagName()
1628
return this.getName();
1633
* Reads one XML element from a java.io.Reader and parses it.
1636
* The reader from which to retrieve the XML data.
1638
* </dl><dl><dt><b>Preconditions:</b></dt><dd>
1639
* <ul><li><code>reader != null</code>
1640
* <li><code>reader</code> is not closed
1643
* <dl><dt><b>Postconditions:</b></dt><dd>
1644
* <ul><li>the state of the receiver is updated to reflect the XML element
1645
* parsed from the reader
1646
* <li>the reader points to the first character following the last
1647
* '>' character of the XML element
1648
* </ul></dd></dl><dl>
1650
* @throws java.io.IOException
1651
* If an error occured while reading the input.
1652
* throws nanoxml.XMLParseException
1653
* If an error occured while parsing the read data.
1655
public void parseFromReader(Reader reader)
1656
throws IOException, XMLParseException
1658
this.parseFromReader(reader, /*startingLineNr*/ 1);
1663
* Reads one XML element from a java.io.Reader and parses it.
1666
* The reader from which to retrieve the XML data.
1667
* @param startingLineNr
1668
* The line number of the first line in the data.
1670
* </dl><dl><dt><b>Preconditions:</b></dt><dd>
1671
* <ul><li><code>reader != null</code>
1672
* <li><code>reader</code> is not closed
1675
* <dl><dt><b>Postconditions:</b></dt><dd>
1676
* <ul><li>the state of the receiver is updated to reflect the XML element
1677
* parsed from the reader
1678
* <li>the reader points to the first character following the last
1679
* '>' character of the XML element
1680
* </ul></dd></dl><dl>
1682
* @throws java.io.IOException
1683
* If an error occured while reading the input.
1684
* throws nanoxml.XMLParseException
1685
* If an error occured while parsing the read data.
1687
public void parseFromReader(Reader reader,
1689
throws IOException, XMLParseException
1693
this.attributes = new Hashtable();
1694
this.children = new Vector();
1695
this.charReadTooMuch = '\0';
1696
this.reader = reader;
1697
this.parserLineNr = startingLineNr;
1700
char ch = this.scanWhitespace();
1703
throw this.expectedInput("<");
1706
ch = this.readChar();
1708
if ((ch == '!') || (ch == '?')) {
1709
this.skipSpecialTag(0);
1711
this.unreadChar(ch);
1712
this.scanElement(this);
1720
* Reads one XML element from a String and parses it.
1723
* The of the XML data.
1725
* </dl><dl><dt><b>Preconditions:</b></dt><dd>
1726
* <ul><li><code>string != null</code>
1727
* <li><code>string.length() > 0</code>
1730
* <dl><dt><b>Postconditions:</b></dt><dd>
1731
* <ul><li>the state of the receiver is updated to reflect the XML element
1732
* parsed from the reader
1733
* </ul></dd></dl><dl>
1735
* throws nanoxml.XMLParseException
1736
* If an error occured while parsing the string.
1738
public void parseString(String string)
1739
throws XMLParseException
1742
this.parseFromReader(new StringReader(string),
1743
/*startingLineNr*/ 1);
1744
} catch (IOException e) {
1745
// Java exception handling suxx
1751
* Reads one XML element from a String and parses it.
1754
* The string ofthe XML data.
1756
* The first character in <code>string</code> to scan.
1758
* </dl><dl><dt><b>Preconditions:</b></dt><dd>
1759
* <ul><li><code>string != null</code>
1760
* <li><code>offset < string.length()</code>
1761
* <li><code>offset >= 0</code>
1764
* <dl><dt><b>Postconditions:</b></dt><dd>
1765
* <ul><li>the state of the receiver is updated to reflect the XML element
1766
* parsed from the reader
1767
* </ul></dd></dl><dl>
1769
* throws nanoxml.XMLParseException
1770
* If an error occured while parsing the string.
1772
public void parseString(String string,
1774
throws XMLParseException
1776
this.parseString(string.substring(offset));
1781
* Reads one XML element from a String and parses it.
1784
* The string of the the XML data.
1786
* The first character in <code>string</code> to scan.
1788
* The character where to stop scanning.
1789
* This character is not scanned.
1791
* </dl><dl><dt><b>Preconditions:</b></dt><dd>
1792
* <ul><li><code>string != null</code>
1793
* <li><code>end <= string.length()</code>
1794
* <li><code>offset < end</code>
1795
* <li><code>offset >= 0</code>
1798
* <dl><dt><b>Postconditions:</b></dt><dd>
1799
* <ul><li>the state of the receiver is updated to reflect the XML element
1800
* parsed from the reader
1801
* </ul></dd></dl><dl>
1803
* throws nanoxml.XMLParseException
1804
* If an error occured while parsing the string.
1806
public void parseString(String string,
1809
throws XMLParseException
1811
this.parseString(string.substring(offset, end));
1816
* Reads one XML element from a String and parses it.
1819
* The string of the the XML data.
1821
* The first character in <code>string</code> to scan.
1823
* The character where to stop scanning.
1824
* This character is not scanned.
1825
* @param startingLineNr
1826
* The line number of the first line in the data.
1828
* </dl><dl><dt><b>Preconditions:</b></dt><dd>
1829
* <ul><li><code>string != null</code>
1830
* <li><code>end <= string.length()</code>
1831
* <li><code>offset < end</code>
1832
* <li><code>offset >= 0</code>
1835
* <dl><dt><b>Postconditions:</b></dt><dd>
1836
* <ul><li>the state of the receiver is updated to reflect the XML element
1837
* parsed from the reader
1838
* </ul></dd></dl><dl>
1840
* throws nanoxml.XMLParseException
1841
* If an error occured while parsing the string.
1843
public void parseString(String string,
1847
throws XMLParseException
1849
string = string.substring(offset, end);
1851
this.parseFromReader(new StringReader(string), startingLineNr);
1852
} catch (IOException e) {
1853
// Java exception handling suxx
1859
* Reads one XML element from a char array and parses it.
1862
* The string of the the XML data.
1864
* The first character in <code>string</code> to scan.
1866
* The character where to stop scanning.
1867
* This character is not scanned.
1869
* </dl><dl><dt><b>Preconditions:</b></dt><dd>
1870
* <ul><li><code>input != null</code>
1871
* <li><code>end <= input.length</code>
1872
* <li><code>offset < end</code>
1873
* <li><code>offset >= 0</code>
1876
* <dl><dt><b>Postconditions:</b></dt><dd>
1877
* <ul><li>the state of the receiver is updated to reflect the XML element
1878
* parsed from the reader
1879
* </ul></dd></dl><dl>
1881
* throws nanoxml.XMLParseException
1882
* If an error occured while parsing the string.
1884
public void parseCharArray(char[] input,
1887
throws XMLParseException
1889
this.parseCharArray(input, offset, end, /*startingLineNr*/ 1);
1894
* Reads one XML element from a char array and parses it.
1897
* The string of the the XML data.
1899
* The first character in <code>string</code> to scan.
1901
* The character where to stop scanning.
1902
* This character is not scanned.
1903
* @param startingLineNr
1904
* The line number of the first line in the data.
1906
* </dl><dl><dt><b>Preconditions:</b></dt><dd>
1907
* <ul><li><code>input != null</code>
1908
* <li><code>end <= input.length</code>
1909
* <li><code>offset < end</code>
1910
* <li><code>offset >= 0</code>
1913
* <dl><dt><b>Postconditions:</b></dt><dd>
1914
* <ul><li>the state of the receiver is updated to reflect the XML element
1915
* parsed from the reader
1916
* </ul></dd></dl><dl>
1918
* throws nanoxml.XMLParseException
1919
* If an error occured while parsing the string.
1921
public void parseCharArray(char[] input,
1925
throws XMLParseException
1928
Reader reader = new CharArrayReader(input, offset, end);
1929
this.parseFromReader(reader, startingLineNr);
1930
} catch (IOException e) {
1931
// This exception will never happen.
1937
* Removes a child element.
1940
* The child element to remove.
1942
* </dl><dl><dt><b>Preconditions:</b></dt><dd>
1943
* <ul><li><code>child != null</code>
1944
* <li><code>child</code> is a child element of the receiver
1947
* <dl><dt><b>Postconditions:</b></dt><dd>
1948
* <ul><li>countChildren() => old.countChildren() - 1
1949
* <li>enumerateChildren() => old.enumerateChildren() - child
1950
* <li>getChildren() => old.enumerateChildren() - child
1951
* </ul></dd></dl><dl>
1953
* see nanoxml.XMLElement#addChild(nanoxml.XMLElement)
1954
* addChild(XMLElement)
1955
* see nanoxml.XMLElement#countChildren()
1956
* see nanoxml.XMLElement#enumerateChildren()
1957
* see nanoxml.XMLElement#getChildren()
1959
public void removeChild(XMLElement child)
1961
this.children.removeElement(child);
1966
* Removes an attribute.
1969
* The name of the attribute.
1971
* </dl><dl><dt><b>Preconditions:</b></dt><dd>
1972
* <ul><li><code>name != null</code>
1973
* <li><code>name</code> is a valid XML identifier
1976
* <dl><dt><b>Postconditions:</b></dt><dd>
1977
* <ul><li>enumerateAttributeNames()
1978
* => old.enumerateAttributeNames() - name
1979
* <li>getAttribute(name) => <code>null</code>
1980
* </ul></dd></dl><dl>
1982
* see nanoxml.XMLElement#enumerateAttributeNames()
1983
* see nanoxml.XMLElement#setDoubleAttribute(java.lang.String, double)
1984
* setDoubleAttribute(String, double)
1985
* see nanoxml.XMLElement#setIntAttribute(java.lang.String, int)
1986
* setIntAttribute(String, int)
1987
* see nanoxml.XMLElement#setAttribute(java.lang.String, java.lang.Object)
1988
* setAttribute(String, Object)
1989
* see nanoxml.XMLElement#getAttribute(java.lang.String)
1990
* getAttribute(String)
1991
* see nanoxml.XMLElement#getAttribute(java.lang.String, java.lang.Object)
1992
* getAttribute(String, Object)
1993
* see nanoxml.XMLElement#getAttribute(java.lang.String,
1994
* java.util.Hashtable,
1995
* java.lang.String, boolean)
1996
* getAttribute(String, Hashtable, String, boolean)
1997
* see nanoxml.XMLElement#getStringAttribute(java.lang.String)
1998
* getStringAttribute(String)
1999
* see nanoxml.XMLElement#getStringAttribute(java.lang.String,
2001
* getStringAttribute(String, String)
2002
* see nanoxml.XMLElement#getStringAttribute(java.lang.String,
2003
* java.util.Hashtable,
2004
* java.lang.String, boolean)
2005
* getStringAttribute(String, Hashtable, String, boolean)
2006
* see nanoxml.XMLElement#getIntAttribute(java.lang.String)
2007
* getIntAttribute(String)
2008
* see nanoxml.XMLElement#getIntAttribute(java.lang.String, int)
2009
* getIntAttribute(String, int)
2010
* see nanoxml.XMLElement#getIntAttribute(java.lang.String,
2011
* java.util.Hashtable,
2012
* java.lang.String, boolean)
2013
* getIntAttribute(String, Hashtable, String, boolean)
2014
* see nanoxml.XMLElement#getDoubleAttribute(java.lang.String)
2015
* getDoubleAttribute(String)
2016
* see nanoxml.XMLElement#getDoubleAttribute(java.lang.String, double)
2017
* getDoubleAttribute(String, double)
2018
* see nanoxml.XMLElement#getDoubleAttribute(java.lang.String,
2019
* java.util.Hashtable,
2020
* java.lang.String, boolean)
2021
* getDoubleAttribute(String, Hashtable, String, boolean)
2022
* see nanoxml.XMLElement#getBooleanAttribute(java.lang.String,
2024
* java.lang.String, boolean)
2025
* getBooleanAttribute(String, String, String, boolean)
2027
public void removeAttribute(String name)
2029
if (this.ignoreCase) {
2030
name = name.toUpperCase();
2032
this.attributes.remove(name);
2037
* Removes an attribute.
2040
* The name of the attribute.
2042
* @deprecated Use {@link #removeAttribute(java.lang.String)
2043
* removeAttribute} instead.
2045
public void removeProperty(String name)
2047
this.removeAttribute(name);
2052
* Removes an attribute.
2055
* The name of the attribute.
2057
* @deprecated Use {@link #removeAttribute(java.lang.String)
2058
* removeAttribute} instead.
2060
public void removeChild(String name)
2062
this.removeAttribute(name);
2067
* Creates a new similar XML element.
2069
* You should override this method when subclassing XMLElement.
2071
protected XMLElement createAnotherElement()
2073
return new XMLElement(this.entities,
2074
this.ignoreWhitespace,
2081
* Changes the content string.
2084
* The new content string.
2086
public void setContent(String content)
2088
this.contents = content;
2093
* Changes the name of the element.
2098
* @deprecated Use {@link #setName(java.lang.String) setName} instead.
2100
public void setTagName(String name)
2107
* Changes the name of the element.
2112
* </dl><dl><dt><b>Preconditions:</b></dt><dd>
2113
* <ul><li><code>name != null</code>
2114
* <li><code>name</code> is a valid XML identifier
2117
* see nanoxml.XMLElement#getName()
2119
public void setName(String name)
2126
* Writes the XML element to a string.
2128
* see nanoxml.XMLElement#write(java.io.Writer) write(Writer)
2130
public String toString()
2133
ByteArrayOutputStream out = new ByteArrayOutputStream();
2134
OutputStreamWriter writer = new OutputStreamWriter(out);
2137
return new String(out.toByteArray());
2138
} catch (IOException e) {
2139
// Java exception handling suxx
2140
return super.toString();
2146
* Writes the XML element to a writer.
2149
* The writer to write the XML data to.
2151
* </dl><dl><dt><b>Preconditions:</b></dt><dd>
2152
* <ul><li><code>writer != null</code>
2153
* <li><code>writer</code> is not closed
2156
* @throws java.io.IOException
2157
* If the data could not be written to the writer.
2159
* see nanoxml.XMLElement#toString()
2161
public void write(Writer writer)
2164
if (this.name == null) {
2165
this.writeEncoded(writer, this.contents);
2169
writer.write(this.name);
2170
if (! this.attributes.isEmpty()) {
2171
Enumeration enumeration = this.attributes.keys();
2172
while (enumeration.hasMoreElements()) {
2174
String key = (String) enumeration.nextElement();
2175
String value = (String) this.attributes.get(key);
2177
writer.write('='); writer.write('"');
2178
this.writeEncoded(writer, value);
2182
if ((this.contents != null) && (this.contents.length() > 0)) {
2184
this.writeEncoded(writer, this.contents);
2185
writer.write('<'); writer.write('/');
2186
writer.write(this.name);
2188
} else if (this.children.isEmpty()) {
2189
writer.write('/'); writer.write('>');
2192
Enumeration enumeration = this.enumerateChildren();
2193
while (enumeration.hasMoreElements()) {
2194
XMLElement child = (XMLElement) enumeration.nextElement();
2195
child.write(writer);
2197
writer.write('<'); writer.write('/');
2198
writer.write(this.name);
2205
* Writes a string encoded to a writer.
2208
* The writer to write the XML data to.
2210
* The string to write encoded.
2212
* </dl><dl><dt><b>Preconditions:</b></dt><dd>
2213
* <ul><li><code>writer != null</code>
2214
* <li><code>writer</code> is not closed
2215
* <li><code>str != null</code>
2218
protected void writeEncoded(Writer writer,
2222
for (int i = 0; i < str.length(); i += 1) {
2223
char ch = str.charAt(i);
2226
writer.write('&'); writer.write('l'); writer.write('t');
2230
writer.write('&'); writer.write('g'); writer.write('t');
2234
writer.write('&'); writer.write('a'); writer.write('m');
2235
writer.write('p'); writer.write(';');
2238
writer.write('&'); writer.write('q'); writer.write('u');
2239
writer.write('o'); writer.write('t'); writer.write(';');
2242
writer.write('&'); writer.write('a'); writer.write('p');
2243
writer.write('o'); writer.write('s'); writer.write(';');
2246
int unicode = (int) ch;
2247
if ((unicode < 32) || (unicode > 126)) {
2248
writer.write('&'); writer.write('#');
2250
writer.write(Integer.toString(unicode, 16));
2261
* Scans an identifier from the current reader.
2262
* The scanned identifier is appended to <code>result</code>.
2265
* The buffer in which the scanned identifier will be put.
2267
* </dl><dl><dt><b>Preconditions:</b></dt><dd>
2268
* <ul><li><code>result != null</code>
2269
* <li>The next character read from the reader is a valid first
2270
* character of an XML identifier.
2273
* <dl><dt><b>Postconditions:</b></dt><dd>
2274
* <ul><li>The next character read from the reader won't be an identifier
2276
* </ul></dd></dl><dl>
2278
protected void scanIdentifier(StringBuffer result)
2282
char ch = this.readChar();
2283
if (((ch < 'A') || (ch > 'Z')) && ((ch < 'a') || (ch > 'z'))
2284
&& ((ch < '0') || (ch > '9')) && (ch != '_') && (ch != '.')
2285
&& (ch != ':') && (ch != '-') && (ch <= '\u007E')) {
2286
this.unreadChar(ch);
2295
* This method scans an identifier from the current reader.
2297
* @return the next character following the whitespace.
2299
protected char scanWhitespace()
2303
char ch = this.readChar();
2318
* This method scans an identifier from the current reader.
2319
* The scanned whitespace is appended to <code>result</code>.
2321
* @return the next character following the whitespace.
2323
* </dl><dl><dt><b>Preconditions:</b></dt><dd>
2324
* <ul><li><code>result != null</code>
2327
protected char scanWhitespace(StringBuffer result)
2331
char ch = this.readChar();
2347
* This method scans a delimited string from the current reader.
2348
* The scanned string without delimiters is appended to
2349
* <code>string</code>.
2351
* </dl><dl><dt><b>Preconditions:</b></dt><dd>
2352
* <ul><li><code>string != null</code>
2353
* <li>the next char read is the string delimiter
2356
protected void scanString(StringBuffer string)
2359
char delimiter = this.readChar();
2360
if ((delimiter != '\'') && (delimiter != '"')) {
2361
throw this.expectedInput("' or \"");
2364
char ch = this.readChar();
2365
if (ch == delimiter) {
2367
} else if (ch == '&') {
2368
this.resolveEntity(string);
2377
* Scans a #PCDATA element. CDATA sections and entities are resolved.
2378
* The next < char is skipped.
2379
* The scanned data is appended to <code>data</code>.
2381
* </dl><dl><dt><b>Preconditions:</b></dt><dd>
2382
* <ul><li><code>data != null</code>
2385
protected void scanPCData(StringBuffer data)
2389
char ch = this.readChar();
2391
ch = this.readChar();
2393
this.checkCDATA(data);
2395
this.unreadChar(ch);
2398
} else if (ch == '&') {
2399
this.resolveEntity(data);
2408
* Scans a special tag and if the tag is a CDATA section, append its
2409
* content to <code>buf</code>.
2411
* </dl><dl><dt><b>Preconditions:</b></dt><dd>
2412
* <ul><li><code>buf != null</code>
2413
* <li>The first < has already been read.
2416
protected boolean checkCDATA(StringBuffer buf)
2419
char ch = this.readChar();
2421
this.unreadChar(ch);
2422
this.skipSpecialTag(0);
2424
} else if (! this.checkLiteral("CDATA[")) {
2425
this.skipSpecialTag(1); // one [ has already been read
2428
int delimiterCharsSkipped = 0;
2429
while (delimiterCharsSkipped < 3) {
2430
ch = this.readChar();
2433
if (delimiterCharsSkipped < 2) {
2434
delimiterCharsSkipped += 1;
2438
delimiterCharsSkipped = 0;
2442
if (delimiterCharsSkipped < 2) {
2443
for (int i = 0; i < delimiterCharsSkipped; i++) {
2446
delimiterCharsSkipped = 0;
2449
delimiterCharsSkipped = 3;
2453
for (int i = 0; i < delimiterCharsSkipped; i += 1) {
2457
delimiterCharsSkipped = 0;
2468
* </dl><dl><dt><b>Preconditions:</b></dt><dd>
2469
* <ul><li>The first <!-- has already been read.
2472
protected void skipComment()
2475
int dashesToRead = 2;
2476
while (dashesToRead > 0) {
2477
char ch = this.readChar();
2484
if (this.readChar() != '>') {
2485
throw this.expectedInput(">");
2491
* Skips a special tag or comment.
2493
* @param bracketLevel The number of open square brackets ([) that have
2494
* already been read.
2496
* </dl><dl><dt><b>Preconditions:</b></dt><dd>
2497
* <ul><li>The first <! has already been read.
2498
* <li><code>bracketLevel >= 0</code>
2501
protected void skipSpecialTag(int bracketLevel)
2504
int tagLevel = 1; // <
2505
char stringDelimiter = '\0';
2506
if (bracketLevel == 0) {
2507
char ch = this.readChar();
2510
} else if (ch == '-') {
2511
ch = this.readChar();
2514
} else if (ch == ']') {
2516
} else if (ch == '-') {
2522
while (tagLevel > 0) {
2523
char ch = this.readChar();
2524
if (stringDelimiter == '\0') {
2525
if ((ch == '"') || (ch == '\'')) {
2526
stringDelimiter = ch;
2527
} else if (bracketLevel <= 0) {
2530
} else if (ch == '>') {
2536
} else if (ch == ']') {
2540
if (ch == stringDelimiter) {
2541
stringDelimiter = '\0';
2549
* Scans the data for literal text.
2550
* Scanning stops when a character does not match or after the complete
2551
* text has been checked, whichever comes first.
2553
* @param literal the literal to check.
2555
* </dl><dl><dt><b>Preconditions:</b></dt><dd>
2556
* <ul><li><code>literal != null</code>
2559
protected boolean checkLiteral(String literal)
2562
int length = literal.length();
2563
for (int i = 0; i < length; i += 1) {
2564
if (this.readChar() != literal.charAt(i)) {
2573
* Reads a character from a reader.
2575
protected char readChar()
2578
if (this.charReadTooMuch != '\0') {
2579
char ch = this.charReadTooMuch;
2580
this.charReadTooMuch = '\0';
2583
int i = this.reader.read();
2585
throw this.unexpectedEndOfData();
2586
} else if (i == 10) {
2587
this.parserLineNr += 1;
2597
* Scans an XML element.
2599
* @param elt The element that will contain the result.
2601
* </dl><dl><dt><b>Preconditions:</b></dt><dd>
2602
* <ul><li>The first < has already been read.
2603
* <li><code>elt != null</code>
2606
protected void scanElement(XMLElement elt)
2609
StringBuffer buf = new StringBuffer();
2610
this.scanIdentifier(buf);
2611
String name = buf.toString();
2613
char ch = this.scanWhitespace();
2614
while ((ch != '>') && (ch != '/')) {
2616
this.unreadChar(ch);
2617
this.scanIdentifier(buf);
2618
String key = buf.toString();
2619
ch = this.scanWhitespace();
2621
throw this.expectedInput("=");
2623
this.unreadChar(this.scanWhitespace());
2625
this.scanString(buf);
2626
elt.setAttribute(key, buf);
2627
ch = this.scanWhitespace();
2630
ch = this.readChar();
2632
throw this.expectedInput(">");
2637
ch = this.scanWhitespace(buf);
2639
this.unreadChar(ch);
2640
this.scanPCData(buf);
2643
ch = this.readChar();
2645
if (this.checkCDATA(buf)) {
2646
this.scanPCData(buf);
2649
ch = this.scanWhitespace(buf);
2651
this.unreadChar(ch);
2652
this.scanPCData(buf);
2657
if ((ch != '/') || this.ignoreWhitespace) {
2661
this.unreadChar(ch);
2667
if (buf.length() == 0) {
2670
ch = this.readChar();
2672
throw this.expectedInput("Comment or Element");
2674
ch = this.readChar();
2676
throw this.expectedInput("Comment or Element");
2680
this.unreadChar(ch);
2681
XMLElement child = this.createAnotherElement();
2682
this.scanElement(child);
2683
elt.addChild(child);
2685
ch = this.scanWhitespace();
2687
throw this.expectedInput("<");
2689
ch = this.readChar();
2691
this.unreadChar(ch);
2693
if (this.ignoreWhitespace) {
2694
elt.setContent(buf.toString().trim());
2696
elt.setContent(buf.toString());
2699
ch = this.readChar();
2701
throw this.expectedInput("/");
2703
this.unreadChar(this.scanWhitespace());
2704
if (! this.checkLiteral(name)) {
2705
throw this.expectedInput(name);
2707
if (this.scanWhitespace() != '>') {
2708
throw this.expectedInput(">");
2714
* Resolves an entity. The name of the entity is read from the reader.
2715
* The value of the entity is appended to <code>buf</code>.
2717
* @param buf Where to put the entity value.
2719
* </dl><dl><dt><b>Preconditions:</b></dt><dd>
2720
* <ul><li>The first & has already been read.
2721
* <li><code>buf != null</code>
2724
protected void resolveEntity(StringBuffer buf)
2728
StringBuffer keyBuf = new StringBuffer();
2730
ch = this.readChar();
2736
String key = keyBuf.toString();
2737
if (key.charAt(0) == '#') {
2739
if (key.charAt(1) == 'x') {
2740
ch = (char) Integer.parseInt(key.substring(2), 16);
2742
ch = (char) Integer.parseInt(key.substring(1), 10);
2744
} catch (NumberFormatException e) {
2745
throw this.unknownEntity(key);
2749
char[] value = (char[]) this.entities.get(key);
2750
if (value == null) {
2751
throw this.unknownEntity(key);
2759
* Pushes a character back to the read-back buffer.
2761
* @param ch The character to push back.
2763
* </dl><dl><dt><b>Preconditions:</b></dt><dd>
2764
* <ul><li>The read-back buffer is empty.
2765
* <li><code>ch != '\0'</code>
2768
protected void unreadChar(char ch)
2770
this.charReadTooMuch = ch;
2775
* Creates a parse exception for when an invalid valueset is given to
2778
* @param name The name of the entity.
2780
* </dl><dl><dt><b>Preconditions:</b></dt><dd>
2781
* <ul><li><code>name != null</code>
2784
protected XMLParseException invalidValueSet(String name)
2786
String msg = "Invalid value set (entity name = \"" + name + "\")";
2787
return new XMLParseException(this.getName(), this.parserLineNr, msg);
2792
* Creates a parse exception for when an invalid value is given to a
2795
* @param name The name of the entity.
2796
* @param value The value of the entity.
2798
* </dl><dl><dt><b>Preconditions:</b></dt><dd>
2799
* <ul><li><code>name != null</code>
2800
* <li><code>value != null</code>
2803
protected XMLParseException invalidValue(String name,
2806
String msg = "Attribute \"" + name + "\" does not contain a valid "
2807
+ "value (\"" + value + "\")";
2808
return new XMLParseException(this.getName(), this.parserLineNr, msg);
2813
* Creates a parse exception for when the end of the data input has been
2816
protected XMLParseException unexpectedEndOfData()
2818
String msg = "Unexpected end of data reached";
2819
return new XMLParseException(this.getName(), this.parserLineNr, msg);
2824
* Creates a parse exception for when a syntax error occured.
2826
* @param context The context in which the error occured.
2828
* </dl><dl><dt><b>Preconditions:</b></dt><dd>
2829
* <ul><li><code>context != null</code>
2830
* <li><code>context.length() > 0</code>
2833
protected XMLParseException syntaxError(String context)
2835
String msg = "Syntax error while parsing " + context;
2836
return new XMLParseException(this.getName(), this.parserLineNr, msg);
2841
* Creates a parse exception for when the next character read is not
2842
* the character that was expected.
2844
* @param charSet The set of characters (in human readable form) that was
2847
* </dl><dl><dt><b>Preconditions:</b></dt><dd>
2848
* <ul><li><code>charSet != null</code>
2849
* <li><code>charSet.length() > 0</code>
2852
protected XMLParseException expectedInput(String charSet)
2854
String msg = "Expected: " + charSet;
2855
return new XMLParseException(this.getName(), this.parserLineNr, msg);
2860
* Creates a parse exception for when an entity could not be resolved.
2862
* @param name The name of the entity.
2864
* </dl><dl><dt><b>Preconditions:</b></dt><dd>
2865
* <ul><li><code>name != null</code>
2866
* <li><code>name.length() > 0</code>
2869
protected XMLParseException unknownEntity(String name)
2871
String msg = "Unknown or invalid entity: &" + name + ";";
2872
return new XMLParseException(this.getName(), this.parserLineNr, msg);