KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jdom > Verifier


1 /*--
2
3  $Id: Verifier.java,v 1.54 2004/12/11 01:31:49 jhunter Exp $
4
5  Copyright (C) 2000-2004 Jason Hunter & Brett McLaughlin.
6  All rights reserved.
7  
8  Redistribution and use in source and binary forms, with or without
9  modification, are permitted provided that the following conditions
10  are met:
11  
12  1. Redistributions of source code must retain the above copyright
13     notice, this list of conditions, and the following disclaimer.
14  
15  2. Redistributions in binary form must reproduce the above copyright
16     notice, this list of conditions, and the disclaimer that follows
17     these conditions in the documentation and/or other materials
18     provided with the distribution.
19
20  3. The name "JDOM" must not be used to endorse or promote products
21     derived from this software without prior written permission. For
22     written permission, please contact <request_AT_jdom_DOT_org>.
23  
24  4. Products derived from this software may not be called "JDOM", nor
25     may "JDOM" appear in their name, without prior written permission
26     from the JDOM Project Management <request_AT_jdom_DOT_org>.
27  
28  In addition, we request (but do not require) that you include in the
29  end-user documentation provided with the redistribution and/or in the
30  software itself an acknowledgement equivalent to the following:
31      "This product includes software developed by the
32       JDOM Project (http://www.jdom.org/)."
33  Alternatively, the acknowledgment may be graphical using the logos
34  available at http://www.jdom.org/images/logos.
35
36  THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
37  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
38  OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
39  DISCLAIMED. IN NO EVENT SHALL THE JDOM AUTHORS OR THE PROJECT
40  CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
41  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
42  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
43  USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
44  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
45  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
46  OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
47  SUCH DAMAGE.
48
49  This software consists of voluntary contributions made by many
50  individuals on behalf of the JDOM Project and was originally
51  created by Jason Hunter <jhunter_AT_jdom_DOT_org> and
52  Brett McLaughlin <brett_AT_jdom_DOT_org>. For more information
53  on the JDOM Project, please see <http://www.jdom.org/>.
54  
55  */

56
57 package org.jdom;
58
59 import java.util.*;
60
61 /**
62  * A utility class to handle well-formedness checks on names, data, and other
63  * verification tasks for JDOM. The class is final and may not be subclassed.
64  *
65  * @version $Revision: 1.54 $, $Date: 2004/12/11 01:31:49 $
66  * @author Brett McLaughlin
67  * @author Elliotte Rusty Harold
68  * @author Jason Hunter
69  * @author Bradley S. Huffman
70  */

71 final public class Verifier {
72
73     private static final String JavaDoc CVS_ID =
74       "@(#) $RCSfile: Verifier.java,v $ $Revision: 1.54 $ $Date: 2004/12/11 01:31:49 $ $Name: $";
75
76     /**
77      * Ensure instantation cannot occur.
78      */

79     private Verifier() { }
80
81     /**
82      * This will check the supplied name to see if it is legal for use as
83      * a JDOM <code>{@link Element}</code> name.
84      *
85      * @param name <code>String</code> name to check.
86      * @return <code>String</code> reason name is illegal, or
87      * <code>null</code> if name is OK.
88      */

89     public static String JavaDoc checkElementName(String JavaDoc name) {
90         // Check basic XML name rules first
91
String JavaDoc reason;
92         if ((reason = checkXMLName(name)) != null) {
93             return reason;
94         }
95
96         // No colons allowed, since elements handle this internally
97
if (name.indexOf(":") != -1) {
98             return "Element names cannot contain colons";
99         }
100
101         // If we got here, everything is OK
102
return null;
103     }
104
105     /**
106      * This will check the supplied name to see if it is legal for use as
107      * a JDOM <code>{@link Attribute}</code> name.
108      *
109      * @param name <code>String</code> name to check.
110      * @return <code>String</code> reason name is illegal, or
111      * <code>null</code> if name is OK.
112      */

113     public static String JavaDoc checkAttributeName(String JavaDoc name) {
114         // Check basic XML name rules first
115
String JavaDoc reason;
116         if ((reason = checkXMLName(name)) != null) {
117             return reason;
118         }
119
120         // No colons are allowed, since attributes handle this internally
121
if (name.indexOf(":") != -1) {
122             return "Attribute names cannot contain colons";
123         }
124
125         // Attribute names may not be xmlns since we do this internally too
126
if (name.equals("xmlns")) {
127             return "An Attribute name may not be \"xmlns\"; " +
128                    "use the Namespace class to manage namespaces";
129         }
130
131         // If we got here, everything is OK
132
return null;
133     }
134     
135     /**
136      * This will check the supplied string to see if it only contains
137      * characters allowed by the XML 1.0 specification. The C0 controls
138      * (e.g. null, vertical tab, formfeed, etc.) are specifically excluded
139      * except for carriage return, linefeed, and the horizontal tab.
140      * Surrogates are also excluded.
141      * <p>
142      * This method is useful for checking element content and attribute
143      * values. Note that characters
144      * like " and &lt; are allowed in attribute values and element content.
145      * They will simply be escaped as &quot; or &lt;
146      * when the value is serialized.
147      * </p>
148      *
149      * @param text <code>String</code> value to check.
150      * @return <code>String</code> reason name is illegal, or
151      * <code>null</code> if name is OK.
152      */

153     public static String JavaDoc checkCharacterData(String JavaDoc text) {
154         if (text == null) {
155             return "A null is not a legal XML value";
156         }
157
158         // Do check
159
for (int i = 0, len = text.length(); i<len; i++) {
160
161             int ch = text.charAt(i);
162             
163             // Check if high part of a surrogate pair
164
if (ch >= 0xD800 && ch <= 0xDBFF) {
165                 // Check if next char is the low-surrogate
166
i++;
167                 if (i < len) {
168                     char low = text.charAt(i);
169                     if (low < 0xDC00 || low > 0xDFFF) {
170                         return "Illegal Surrogate Pair";
171                     }
172                     // It's a good pair, calculate the true value of
173
// the character to then fall thru to isXMLCharacter
174
ch = 0x10000 + (ch - 0xD800) * 0x400 + (low - 0xDC00);
175                 }
176                 else {
177                     return "Surrogate Pair Truncated";
178                 }
179             }
180
181             if (!isXMLCharacter(ch)) {
182                 // Likely this character can't be easily displayed
183
// because it's a control so we use it'd hexadecimal
184
// representation in the reason.
185
return ("0x" + Integer.toHexString(ch) +
186                         " is not a legal XML character");
187             }
188         }
189
190         // If we got here, everything is OK
191
return null;
192     }
193
194     /**
195      * This will check the supplied data to see if it is legal for use as
196      * JDOM <code>{@link CDATA}</code>.
197      *
198      * @param data <code>String</code> data to check.
199      * @return <code>String</code> reason data is illegal, or
200      * <code>null</code> is name is OK.
201      */

202     public static String JavaDoc checkCDATASection(String JavaDoc data) {
203         String JavaDoc reason = null;
204         if ((reason = checkCharacterData(data)) != null) {
205             return reason;
206         }
207
208         if (data.indexOf("]]>") != -1) {
209             return "CDATA cannot internally contain a CDATA ending " +
210                    "delimiter (]]>)";
211         }
212
213         // If we got here, everything is OK
214
return null;
215     }
216
217     /**
218      * This will check the supplied name to see if it is legal for use as
219      * a JDOM <code>{@link Namespace}</code> prefix.
220      *
221      * @param prefix <code>String</code> prefix to check.
222      * @return <code>String</code> reason name is illegal, or
223      * <code>null</code> if name is OK.
224      */

225     public static String JavaDoc checkNamespacePrefix(String JavaDoc prefix) {
226         // Manually do rules, since URIs can be null or empty
227
if ((prefix == null) || (prefix.equals(""))) {
228             return null;
229         }
230
231         // Cannot start with a number
232
char first = prefix.charAt(0);
233         if (isXMLDigit(first)) {
234             return "Namespace prefixes cannot begin with a number";
235         }
236         // Cannot start with a $
237
if (first == '$') {
238             return "Namespace prefixes cannot begin with a dollar sign ($)";
239         }
240         // Cannot start with a -
241
if (first == '-') {
242             return "Namespace prefixes cannot begin with a hyphen (-)";
243         }
244         // Cannot start with a .
245
if (first == '.') {
246             return "Namespace prefixes cannot begin with a period (.)";
247         }
248         // Cannot start with "xml" in any character case
249
if (prefix.toLowerCase().startsWith("xml")) {
250             return "Namespace prefixes cannot begin with " +
251                    "\"xml\" in any combination of case";
252         }
253
254         // Ensure legal content
255
for (int i=0, len = prefix.length(); i<len; i++) {
256             char c = prefix.charAt(i);
257             if (!isXMLNameCharacter(c)) {
258                 return "Namespace prefixes cannot contain the character \"" +
259                         c + "\"";
260             }
261         }
262
263         // No colons allowed
264
if (prefix.indexOf(":") != -1) {
265             return "Namespace prefixes cannot contain colons";
266         }
267
268         // If we got here, everything is OK
269
return null;
270     }
271
272     /**
273      * This will check the supplied name to see if it is legal for use as
274      * a JDOM <code>{@link Namespace}</code> URI.
275      *
276      * @param uri <code>String</code> URI to check.
277      * @return <code>String</code> reason name is illegal, or
278      * <code>null</code> if name is OK.
279      */

280     public static String JavaDoc checkNamespaceURI(String JavaDoc uri) {
281         // Manually do rules, since URIs can be null or empty
282
if ((uri == null) || (uri.equals(""))) {
283             return null;
284         }
285
286         // Cannot start with a number
287
char first = uri.charAt(0);
288         if (Character.isDigit(first)) {
289             return "Namespace URIs cannot begin with a number";
290         }
291         // Cannot start with a $
292
if (first == '$') {
293             return "Namespace URIs cannot begin with a dollar sign ($)";
294         }
295         // Cannot start with a -
296
if (first == '-') {
297             return "Namespace URIs cannot begin with a hyphen (-)";
298         }
299
300         // If we got here, everything is OK
301
return null;
302     }
303
304     /**
305      * Check if two namespaces collide.
306      *
307      * @param namespace <code>Namespace</code> to check.
308      * @param other <code>Namespace</code> to check against.
309      * @return <code>String</code> reason for collision, or
310      * <code>null</code> if no collision.
311      */

312     public static String JavaDoc checkNamespaceCollision(Namespace namespace,
313                                                  Namespace other) {
314         String JavaDoc p1,p2,u1,u2,reason;
315
316         reason = null;
317         p1 = namespace.getPrefix();
318         u1 = namespace.getURI();
319         p2 = other.getPrefix();
320         u2 = other.getURI();
321         if (p1.equals(p2) && !u1.equals(u2)) {
322             reason = "The namespace prefix \"" + p1 + "\" collides";
323         }
324         return reason;
325     }
326
327     /**
328      * Check if <code>{@link Attribute}</code>'s namespace collides with a
329      * <code>{@link Element}</code>'s namespace.
330      *
331      * @param attribute <code>Attribute</code> to check.
332      * @param element <code>Element</code> to check against.
333      * @return <code>String</code> reason for collision, or
334      * <code>null</code> if no collision.
335      */

336     public static String JavaDoc checkNamespaceCollision(Attribute attribute,
337                                                  Element element) {
338         Namespace namespace = attribute.getNamespace();
339         String JavaDoc prefix = namespace.getPrefix();
340         if ("".equals(prefix)) {
341             return null;
342         }
343
344         return checkNamespaceCollision(namespace, element);
345     }
346
347     /**
348      * Check if a <code>{@link Namespace}</code> collides with a
349      * <code>{@link Element}</code>'s namespace.
350      *
351      * @param namespace <code>Namespace</code> to check.
352      * @param element <code>Element</code> to check against.
353      * @return <code>String</code> reason for collision, or
354      * <code>null</code> if no collision.
355      */

356     public static String JavaDoc checkNamespaceCollision(Namespace namespace,
357                                                  Element element) {
358         String JavaDoc reason = checkNamespaceCollision(namespace,
359                                                 element.getNamespace());
360         if (reason != null) {
361             return reason + " with the element namespace prefix";
362         }
363
364         reason = checkNamespaceCollision(namespace,
365                                          element.getAdditionalNamespaces());
366         if (reason != null) {
367             return reason;
368         }
369
370         reason = checkNamespaceCollision(namespace, element.getAttributes());
371         if (reason != null) {
372             return reason;
373         }
374
375         return null;
376     }
377
378     /**
379      * Check if a <code>{@link Namespace}</code> collides with a
380      * <code>{@link Attribute}</code>'s namespace.
381      *
382      * @param namespace <code>Namespace</code> to check.
383      * @param attribute <code>Attribute</code> to check against.
384      * @return <code>String</code> reason for collision, or
385      * <code>null</code> if no collision.
386      */

387     public static String JavaDoc checkNamespaceCollision(Namespace namespace,
388                                                  Attribute attribute) {
389         String JavaDoc reason = checkNamespaceCollision(namespace,
390                                                 attribute.getNamespace());
391         if (reason != null) {
392             reason += " with an attribute namespace prefix on the element";
393         }
394         return reason;
395     }
396
397     /**
398      * Check if a <code>{@link Namespace}</code> collides with any namespace
399      * from a list of objects.
400      *
401      * @param namespace <code>Namespace</code> to check.
402      * @param list <code>List</code> to check against.
403      * @return <code>String</code> reason for collision, or
404      * <code>null</code> if no collision.
405      */

406     public static String JavaDoc checkNamespaceCollision(Namespace namespace,
407                                                  List list) {
408         if (list == null) {
409             return null;
410         }
411
412         String JavaDoc reason = null;
413         Iterator i = list.iterator();
414         while ((reason == null) && i.hasNext()) {
415             Object JavaDoc obj = i.next();
416             if (obj instanceof Attribute) {
417                 reason = checkNamespaceCollision(namespace, (Attribute) obj);
418             }
419             else if (obj instanceof Element) {
420                 reason = checkNamespaceCollision(namespace, (Element) obj);
421             }
422             else if (obj instanceof Namespace) {
423                 reason = checkNamespaceCollision(namespace, (Namespace) obj);
424                 if (reason != null) {
425                     reason += " with an additional namespace declared" +
426                               " by the element";
427                 }
428             }
429         }
430         return reason;
431     }
432
433     /**
434      * This will check the supplied data to see if it is legal for use as
435      * a JDOM <code>{@link ProcessingInstruction}</code> target.
436      *
437      * @param target <code>String</code> target to check.
438      * @return <code>String</code> reason target is illegal, or
439      * <code>null</code> if target is OK.
440      */

441     public static String JavaDoc checkProcessingInstructionTarget(String JavaDoc target) {
442         // Check basic XML name rules first
443
String JavaDoc reason;
444         if ((reason = checkXMLName(target)) != null) {
445             return reason;
446         }
447
448         // No colons allowed, per Namespace Specification Section 6
449
if (target.indexOf(":") != -1) {
450             return "Processing instruction targets cannot contain colons";
451         }
452
453         // Cannot begin with 'xml' in any case
454
if (target.equalsIgnoreCase("xml")) {
455             return "Processing instructions cannot have a target of " +
456                    "\"xml\" in any combination of case. (Note that the " +
457                    "\"<?xml ... ?>\" declaration at the beginning of a " +
458                    "document is not a processing instruction and should not " +
459                    "be added as one; it is written automatically during " +
460                    "output, e.g. by XMLOutputter.)";
461         }
462
463         // If we got here, everything is OK
464
return null;
465     }
466
467    /**
468      * This will check the supplied data to see if it is legal for use as
469      * <code>{@link ProcessingInstruction}</code> data. Besides checking that
470      * all the characters are allowed in XML, this also checks
471      * that the data does not contain the PI end-string "?&gt;".
472      *
473      * @param data <code>String</code> data to check.
474      * @return <code>String</code> reason data is illegal, or
475      * <code>null</code> if data is OK.
476      */

477     public static String JavaDoc checkProcessingInstructionData(String JavaDoc data) {
478         // Check basic XML name rules first
479
String JavaDoc reason = checkCharacterData(data);
480
481         if (reason == null) {
482             if (data.indexOf("?>") >= 0) {
483                 return "Processing instructions cannot contain " +
484                        "the string \"?>\"";
485             }
486         }
487
488         return reason;
489     }
490
491     /**
492      * This will check the supplied data to see if it is legal for use as
493      * JDOM <code>{@link Comment}</code> data.
494      *
495      * @param data <code>String</code> data to check.
496      * @return <code>String</code> reason data is illegal, or
497      * <code>null</code> if data is OK.
498      */

499     public static String JavaDoc checkCommentData(String JavaDoc data) {
500         String JavaDoc reason = null;
501         if ((reason = checkCharacterData(data)) != null) {
502             return reason;
503         }
504
505         if (data.indexOf("--") != -1) {
506             return "Comments cannot contain double hyphens (--)";
507         }
508         if (data.endsWith("-")) {
509             return "Comment data cannot end with a hyphen.";
510         }
511
512         // If we got here, everything is OK
513
return null;
514     }
515
516     // [13] PubidChar ::= #x20 | #xD | #xA | [a-zA-Z0-9] |
517
// [-'()+,./:=?;*#@$_%]
518
public static boolean isXMLPublicIDCharacter(char c) {
519
520         if (c >= 'a' && c <= 'z') return true;
521         if (c >= '?' && c <= 'Z') return true;
522         if (c >= '\'' && c <= ';') return true;
523
524         if (c == ' ') return true;
525         if (c == '!') return true;
526         if (c == '=') return true;
527         if (c == '#') return true;
528         if (c == '$') return true;
529         if (c == '_') return true;
530         if (c == '%') return true;
531         if (c == '\n') return true;
532         if (c == '\r') return true;
533         if (c == '\t') return true;
534
535         return false;
536     }
537
538     /**
539      * This will ensure that the data for a public identifier
540      * is legal.
541      *
542      * @param publicID <code>String</code> public ID to check.
543      * @return <code>String</code> reason public ID is illegal, or
544      * <code>null</code> if public ID is OK.
545      */

546     public static String JavaDoc checkPublicID(String JavaDoc publicID) {
547         String JavaDoc reason = null;
548
549         if (publicID == null) return null;
550         // This indicates there is no public ID
551

552         for (int i = 0; i < publicID.length(); i++) {
553           char c = publicID.charAt(i);
554           if (!isXMLPublicIDCharacter(c)) {
555             reason = c + " is not a legal character in public IDs";
556             break;
557           }
558         }
559
560         return reason;
561     }
562
563
564     /**
565      * This will ensure that the data for a system literal
566      * is legal.
567      *
568      * @param systemLiteral <code>String</code> system literal to check.
569      * @return <code>String</code> reason system literal is illegal, or
570      * <code>null</code> if system literal is OK.
571      */

572     public static String JavaDoc checkSystemLiteral(String JavaDoc systemLiteral) {
573         String JavaDoc reason = null;
574
575         if (systemLiteral == null) return null;
576         // This indicates there is no system ID
577

578         if (systemLiteral.indexOf('\'') != -1
579           && systemLiteral.indexOf('"') != -1) {
580             reason =
581              "System literals cannot simultaneously contain both single and double quotes.";
582         }
583         else {
584           reason = checkCharacterData(systemLiteral);
585         }
586
587         return reason;
588     }
589
590     /**
591      * This is a utility function for sharing the base process of checking
592      * any XML name.
593      *
594      * @param name <code>String</code> to check for XML name compliance.
595      * @return <code>String</code> reason the name is illegal, or
596      * <code>null</code> if OK.
597      */

598     public static String JavaDoc checkXMLName(String JavaDoc name) {
599         // Cannot be empty or null
600
if ((name == null) || (name.length() == 0)
601                            || (name.trim().equals(""))) {
602             return "XML names cannot be null or empty";
603         }
604
605       
606         // Cannot start with a number
607
char first = name.charAt(0);
608         if (!isXMLNameStartCharacter(first)) {
609             return "XML names cannot begin with the character \"" +
610                    first + "\"";
611         }
612         // Ensure legal content for non-first chars
613
for (int i=1, len = name.length(); i<len; i++) {
614             char c = name.charAt(i);
615             if (!isXMLNameCharacter(c)) {
616                 return "XML names cannot contain the character \"" + c + "\"";
617             }
618         }
619
620         // We got here, so everything is OK
621
return null;
622     }
623
624    /**
625      * <p>
626      * Checks a string to see if it is a legal RFC 2396 URI.
627      * Both absolute and relative URIs are supported.
628      * </p>
629      *
630      * @param uri <code>String</code> to check.
631      * @return <code>String</code> reason the URI is illegal, or
632      * <code>null</code> if OK.
633      */

634     public static String JavaDoc checkURI(String JavaDoc uri) {
635         // URIs can be null or empty
636
if ((uri == null) || (uri.equals(""))) {
637             return null;
638         }
639
640         for (int i = 0; i < uri.length(); i++) {
641             char test = uri.charAt(i);
642             if (!isURICharacter(test)) {
643                 String JavaDoc msgNumber = "0x" + Integer.toHexString(test);
644                 if (test <= 0x09) msgNumber = "0x0" + Integer.toHexString(test);
645                 return "URIs cannot contain " + msgNumber;
646             } // end if
647
if (test == '%') { // must be followed by two hexadecimal digits
648
try {
649                        char firstDigit = uri.charAt(i+1);
650                        char secondDigit = uri.charAt(i+2);
651                        if (!isHexDigit(firstDigit) ||
652                            !isHexDigit(secondDigit)) {
653                            return "Percent signs in URIs must be followed by "
654                             + "exactly two hexadecimal digits.";
655                        }
656
657                    }
658                    catch (StringIndexOutOfBoundsException JavaDoc e) {
659                        return "Percent signs in URIs must be followed by "
660                         + "exactly two hexadecimal digits.";
661                    }
662             }
663         } // end for
664

665         // If we got here, everything is OK
666
return null;
667     }
668
669    /**
670      * <p>
671      * This is a utility function for determining whether a specified
672      * Unicode character is a hexadecimal digit as defined in RFC 2396;
673      * that is, one of the ASCII characters 0-9, a-f, or A-F.
674      * </p>
675      *
676      * @param c to check for hex digit.
677      * @return true if it's allowed, false otherwise.
678      */

679     public static boolean isHexDigit(char c) {
680
681     // I suspect most characters passed to this method will be
682
// correct hexadecimal digits, so I test for the true cases
683
// first. If this proves to be a performance bottleneck
684
// a switch statement or lookup table
685
// might optimize this.
686
if (c >= '0' && c <= '9') return true;
687         if (c >= 'A' && c <= 'F') return true;
688         if (c >= 'a' && c <= 'f') return true;
689
690         return false;
691     }
692
693     /**
694      * <p>
695      * This is a utility function for determining whether
696      * a specified Unicode character is legal in URI references
697      * as determined by RFC 2396.
698      * </p>
699      *
700      * @param c <code>char</code> to check for URI reference compliance.
701      * @return true if it's allowed, false otherwise.
702      */

703     public static boolean isURICharacter(char c) {
704         if (c >= 'a' && c <= 'z') return true;
705         if (c >= 'A' && c <= 'Z') return true;
706         if (c >= '0' && c <= '9') return true;
707         if (c == '/') return true;
708         if (c == '-') return true;
709         if (c == '.') return true;
710         if (c == '?') return true;
711         if (c == ':') return true;
712         if (c == '@') return true;
713         if (c == '&') return true;
714         if (c == '=') return true;
715         if (c == '+') return true;
716         if (c == '$') return true;
717         if (c == ',') return true;
718         if (c == '%') return true;
719
720         if (c == '_') return true;
721         if (c == '!') return true;
722         if (c == '~') return true;
723         if (c == '*') return true;
724         if (c == '\'') return true;
725         if (c == '(') return true;
726         if (c == ')') return true;
727         return false;
728     }
729     
730     /**
731      * This is a utility function for determining whether a specified
732      * character is a character according to production 2 of the
733      * XML 1.0 specification.
734      *
735      * @param c <code>char</code> to check for XML compliance
736      * @return <code>boolean</code> true if it's a character,
737      * false otherwise
738      */

739     public static boolean isXMLCharacter(int c) {
740     
741         if (c == '\n') return true;
742         if (c == '\r') return true;
743         if (c == '\t') return true;
744         
745         if (c < 0x20) return false; if (c <= 0xD7FF) return true;
746         if (c < 0xE000) return false; if (c <= 0xFFFD) return true;
747         if (c < 0x10000) return false; if (c <= 0x10FFFF) return true;
748         
749         return false;
750     }
751
752
753     /**
754      * This is a utility function for determining whether a specified
755      * character is a name character according to production 4 of the
756      * XML 1.0 specification.
757      *
758      * @param c <code>char</code> to check for XML name compliance.
759      * @return <code>boolean</code> true if it's a name character,
760      * false otherwise.
761      */

762     public static boolean isXMLNameCharacter(char c) {
763     
764       return (isXMLLetter(c) || isXMLDigit(c) || c == '.' || c == '-'
765                              || c == '_' || c == ':' || isXMLCombiningChar(c)
766                              || isXMLExtender(c));
767     }
768
769     /**
770      * This is a utility function for determining whether a specified
771      * character is a legal name start character according to production 5
772      * of the XML 1.0 specification. This production does allow names
773      * to begin with colons which the Namespaces in XML Recommendation
774      * disallows.
775      *
776      * @param c <code>char</code> to check for XML name start compliance.
777      * @return <code>boolean</code> true if it's a name start character,
778      * false otherwise.
779      */

780     public static boolean isXMLNameStartCharacter(char c) {
781     
782       return (isXMLLetter(c) || c == '_' || c ==':');
783     
784     }
785
786     /**
787      * This is a utility function for determining whether a specified
788      * character is a letter or digit according to productions 84 and 88
789      * of the XML 1.0 specification.
790      *
791      * @param c <code>char</code> to check.
792      * @return <code>boolean</code> true if it's letter or digit,
793      * false otherwise.
794      */

795     public static boolean isXMLLetterOrDigit(char c) {
796     
797       return (isXMLLetter(c) || isXMLDigit(c));
798     
799     }
800
801     /**
802      * This is a utility function for determining whether a specified character
803      * is a letter according to production 84 of the XML 1.0 specification.
804      *
805      * @param c <code>char</code> to check for XML name compliance.
806      * @return <code>String</code> true if it's a letter, false otherwise.
807      */

808     public static boolean isXMLLetter(char c) {
809         // Note that order is very important here. The search proceeds
810
// from lowest to highest values, so that no searching occurs
811
// above the character's value. BTW, the first line is equivalent to:
812
// if (c >= 0x0041 && c <= 0x005A) return true;
813

814         if (c < 0x0041) return false; if (c <= 0x005a) return true;
815         if (c < 0x0061) return false; if (c <= 0x007A) return true;
816         if (c < 0x00C0) return false; if (c <= 0x00D6) return true;
817         if (c < 0x00D8) return false; if (c <= 0x00F6) return true;
818         if (c < 0x00F8) return false; if (c <= 0x00FF) return true;
819         if (c < 0x0100) return false; if (c <= 0x0131) return true;
820         if (c < 0x0134) return false; if (c <= 0x013E) return true;
821         if (c < 0x0141) return false; if (c <= 0x0148) return true;
822         if (c < 0x014A) return false; if (c <= 0x017E) return true;
823         if (c < 0x0180) return false; if (c <= 0x01C3) return true;
824         if (c < 0x01CD) return false; if (c <= 0x01F0) return true;
825         if (c < 0x01F4) return false; if (c <= 0x01F5) return true;
826         if (c < 0x01FA) return false; if (c <= 0x0217) return true;
827         if (c < 0x0250) return false; if (c <= 0x02A8) return true;
828         if (c < 0x02BB) return false; if (c <= 0x02C1) return true;
829         if (c == 0x0386) return true;
830         if (c < 0x0388) return false; if (c <= 0x038A) return true;
831         if (c == 0x038C) return true;
832         if (c < 0x038E) return false; if (c <= 0x03A1) return true;
833         if (c < 0x03A3) return false; if (c <= 0x03CE) return true;
834         if (c < 0x03D0) return false; if (c <= 0x03D6) return true;
835         if (c == 0x03DA) return true;
836         if (c == 0x03DC) return true;
837         if (c == 0x03DE) return true;
838         if (c == 0x03E0) return true;
839         if (c < 0x03E2) return false; if (c <= 0x03F3) return true;
840         if (c < 0x0401) return false; if (c <= 0x040C) return true;
841         if (c < 0x040E) return false; if (c <= 0x044F) return true;
842         if (c < 0x0451) return false; if (c <= 0x045C) return true;
843         if (c < 0x045E) return false; if (c <= 0x0481) return true;
844         if (c < 0x0490) return false; if (c <= 0x04C4) return true;
845         if (c < 0x04C7) return false; if (c <= 0x04C8) return true;
846         if (c < 0x04CB) return false; if (c <= 0x04CC) return true;
847         if (c < 0x04D0) return false; if (c <= 0x04EB) return true;
848         if (c < 0x04EE) return false; if (c <= 0x04F5) return true;
849         if (c < 0x04F8) return false; if (c <= 0x04F9) return true;
850         if (c < 0x0531) return false; if (c <= 0x0556) return true;
851         if (c == 0x0559) return true;
852         if (c < 0x0561) return false; if (c <= 0x0586) return true;
853         if (c < 0x05D0) return false; if (c <= 0x05EA) return true;
854         if (c < 0x05F0) return false; if (c <= 0x05F2) return true;
855         if (c < 0x0621) return false; if (c <= 0x063A) return true;
856         if (c < 0x0641) return false; if (c <= 0x064A) return true;
857         if (c < 0x0671) return false; if (c <= 0x06B7) return true;
858         if (c < 0x06BA) return false; if (c <= 0x06BE) return true;
859         if (c < 0x06C0) return false; if (c <= 0x06CE) return true;
860         if (c < 0x06D0) return false; if (c <= 0x06D3) return true;
861         if (c == 0x06D5) return true;
862         if (c < 0x06E5) return false; if (c <= 0x06E6) return true;
863         if (c < 0x0905) return false; if (c <= 0x0939) return true;
864         if (c == 0x093D) return true;
865         if (c < 0x0958) return false; if (c <= 0x0961) return true;
866         if (c < 0x0985) return false; if (c <= 0x098C) return true;
867         if (c < 0x098F) return false; if (c <= 0x0990) return true;
868         if (c < 0x0993) return false; if (c <= 0x09A8) return true;
869         if (c < 0x09AA) return false; if (c <= 0x09B0) return true;
870         if (c == 0x09B2) return true;
871         if (c < 0x09B6) return false; if (c <= 0x09B9) return true;
872         if (c < 0x09DC) return false; if (c <= 0x09DD) return true;
873         if (c < 0x09DF) return false; if (c <= 0x09E1) return true;
874         if (c < 0x09F0) return false; if (c <= 0x09F1) return true;
875         if (c < 0x0A05) return false; if (c <= 0x0A0A) return true;
876         if (c < 0x0A0F) return false; if (c <= 0x0A10) return true;
877         if (c < 0x0A13) return false; if (c <= 0x0A28) return true;
878         if (c < 0x0A2A) return false; if (c <= 0x0A30) return true;
879         if (c < 0x0A32) return false; if (c <= 0x0A33) return true;
880         if (c < 0x0A35) return false; if (c <= 0x0A36) return true;
881         if (c < 0x0A38) return false; if (c <= 0x0A39) return true;
882         if (c < 0x0A59) return false; if (c <= 0x0A5C) return true;
883         if (c == 0x0A5E) return true;
884         if (c < 0x0A72) return false; if (c <= 0x0A74) return true;
885         if (c < 0x0A85) return false; if (c <= 0x0A8B) return true;
886         if (c == 0x0A8D) return true;
887         if (c < 0x0A8F) return false; if (c <= 0x0A91) return true;
888         if (c < 0x0A93) return false; if (c <= 0x0AA8) return true;
889         if (c < 0x0AAA) return false; if (c <= 0x0AB0) return true;
890         if (c < 0x0AB2) return false; if (c <= 0x0AB3) return true;
891         if (c < 0x0AB5) return false; if (c <= 0x0AB9) return true;
892         if (c == 0x0ABD) return true;
893         if (c == 0x0AE0) return true;
894         if (c < 0x0B05) return false; if (c <= 0x0B0C) return true;
895         if (c < 0x0B0F) return false; if (c <= 0x0B10) return true;
896         if (c < 0x0B13) return false; if (c <= 0x0B28) return true;
897         if (c < 0x0B2A) return false; if (c <= 0x0B30) return true;
898         if (c < 0x0B32) return false; if (c <= 0x0B33) return true;
899         if (c < 0x0B36) return false; if (c <= 0x0B39) return true;
900         if (c == 0x0B3D) return true;
901         if (c < 0x0B5C) return false; if (c <= 0x0B5D) return true;
902         if (c < 0x0B5F) return false; if (c <= 0x0B61) return true;
903         if (c < 0x0B85) return false; if (c <= 0x0B8A) return true;
904         if (c < 0x0B8E) return false; if (c <= 0x0B90) return true;
905         if (c < 0x0B92) return false; if (c <= 0x0B95) return true;
906         if (c < 0x0B99) return false; if (c <= 0x0B9A) return true;
907         if (c == 0x0B9C) return true;
908         if (c < 0x0B9E) return false; if (c <= 0x0B9F) return true;
909         if (c < 0x0BA3) return false; if (c <= 0x0BA4) return true;
910         if (c < 0x0BA8) return false; if (c <= 0x0BAA) return true;
911         if (c < 0x0BAE) return false; if (c <= 0x0BB5) return true;
912         if (c < 0x0BB7) return false; if (c <= 0x0BB9) return true;
913         if (c < 0x0C05) return false; if (c <= 0x0C0C) return true;
914         if (c < 0x0C0E) return false; if (c <= 0x0C10) return true;
915         if (c < 0x0C12) return false; if (c <= 0x0C28) return true;
916         if (c < 0x0C2A) return false; if (c <= 0x0C33) return true;
917         if (c < 0x0C35) return false; if (c <= 0x0C39) return true;
918         if (c < 0x0C60) return false; if (c <= 0x0C61) return true;
919         if (c < 0x0C85) return false; if (c <= 0x0C8C) return true;
920         if (c < 0x0C8E) return false; if (c <= 0x0C90) return true;
921         if (c < 0x0C92) return false; if (c <= 0x0CA8) return true;
922         if (c < 0x0CAA) return false; if (c <= 0x0CB3) return true;
923         if (c < 0x0CB5) return false; if (c <= 0x0CB9) return true;
924         if (c == 0x0CDE) return true;
925         if (c < 0x0CE0) return false; if (c <= 0x0CE1) return true;
926         if (c < 0x0D05) return false; if (c <= 0x0D0C) return true;
927         if (c < 0x0D0E) return false; if (c <= 0x0D10) return true;
928         if (c < 0x0D12) return false; if (c <= 0x0D28) return true;
929         if (c < 0x0D2A) return false; if (c <= 0x0D39) return true;
930         if (c < 0x0D60) return false; if (c <= 0x0D61) return true;
931         if (c < 0x0E01) return false; if (c <= 0x0E2E) return true;
932         if (c == 0x0E30) return true;
933         if (c < 0x0E32) return false; if (c <= 0x0E33) return true;
934         if (c < 0x0E40) return false; if (c <= 0x0E45) return true;
935         if (c < 0x0E81) return false; if (c <= 0x0E82) return true;
936         if (c == 0x0E84) return true;
937         if (c < 0x0E87) return false; if (c <= 0x0E88) return true;
938         if (c == 0x0E8A) return true;
939         if (c == 0x0E8D) return true;
940         if (c < 0x0E94) return false; if (c <= 0x0E97) return true;
941         if (c < 0x0E99) return false; if (c <= 0x0E9F) return true;
942         if (c < 0x0EA1) return false; if (c <= 0x0EA3) return true;
943         if (c == 0x0EA5) return true;
944         if (c == 0x0EA7) return true;
945         if (c < 0x0EAA) return false; if (c <= 0x0EAB) return true;
946         if (c < 0x0EAD) return false; if (c <= 0x0EAE) return true;
947         if (c == 0x0EB0) return true;
948         if (c < 0x0EB2) return false; if (c <= 0x0EB3) return true;
949         if (c == 0x0EBD) return true;
950         if (c < 0x0EC0) return false; if (c <= 0x0EC4) return true;
951         if (c < 0x0F40) return false; if (c <= 0x0F47) return true;
952         if (c < 0x0F49) return false; if (c <= 0x0F69) return true;
953         if (c < 0x10A0) return false; if (c <= 0x10C5) return true;
954         if (c < 0x10D0) return false; if (c <= 0x10F6) return true;
955         if (c == 0x1100) return true;
956         if (c < 0x1102) return false; if (c <= 0x1103) return true;
957         if (c < 0x1105) return false; if (c <= 0x1107) return true;
958         if (c == 0x1109) return true;
959         if (c < 0x110B) return false; if (c <= 0x110C) return true;
960         if (c < 0x110E) return false; if (c <= 0x1112) return true;
961         if (c == 0x113C) return true;
962         if (c == 0x113E) return true;
963         if (c == 0x1140) return true;
964         if (c == 0x114C) return true;
965         if (c == 0x114E) return true;
966         if (c == 0x1150) return true;
967         if (c < 0x1154) return false; if (c <= 0x1155) return true;
968         if (c == 0x1159) return true;
969         if (c < 0x115F) return false; if (c <= 0x1161) return true;
970         if (c == 0x1163) return true;
971         if (c == 0x1165) return true;
972         if (c == 0x1167) return true;
973         if (c == 0x1169) return true;
974         if (c < 0x116D) return false; if (c <= 0x116E) return true;
975         if (c < 0x1172) return false; if (c <= 0x1173) return true;
976         if (c == 0x1175) return true;
977         if (c == 0x119E) return true;
978         if (c == 0x11A8) return true;
979         if (c == 0x11AB) return true;
980         if (c < 0x11AE) return false; if (c <= 0x11AF) return true;
981         if (c < 0x11B7) return false; if (c <= 0x11B8) return true;
982         if (c == 0x11BA) return true;
983         if (c < 0x11BC) return false; if (c <= 0x11C2) return true;
984         if (c == 0x11EB) return true;
985         if (c == 0x11F0) return true;
986         if (c == 0x11F9) return true;
987         if (c < 0x1E00) return false; if (c <= 0x1E9B) return true;
988         if (c < 0x1EA0) return false; if (c <= 0x1EF9) return true;
989         if (c < 0x1F00) return false; if (c <= 0x1F15) return true;
990         if (c < 0x1F18) return false; if (c <= 0x1F1D) return true;
991         if (c < 0x1F20) return false; if (c <= 0x1F45) return true;
992         if (c < 0x1F48) return false; if (c <= 0x1F4D) return true;
993         if (c < 0x1F50) return false; if (c <= 0x1F57) return true;
994         if (c == 0x1F59) return true;
995         if (c == 0x1F5B) return true;
996         if (c == 0x1F5D) return true;
997         if (c < 0x1F5F) return false; if (c <= 0x1F7D) return true;
998         if (c < 0x1F80) return false; if (c <= 0x1FB4) return true;
999         if (c < 0x1FB6) return false; if (c <= 0x1FBC) return true;
1000        if (c == 0x1FBE) return true;
1001        if (c < 0x1FC2) return false; if (c <= 0x1FC4) return true;
1002        if (c < 0x1FC6) return false; if (c <= 0x1FCC) return true;
1003        if (c < 0x1FD0) return false; if (c <= 0x1FD3) return true;
1004        if (c < 0x1FD6) return false; if (c <= 0x1FDB) return true;
1005        if (c < 0x1FE0) return false; if (c <= 0x1FEC) return true;
1006        if (c < 0x1FF2) return false; if (c <= 0x1FF4) return true;
1007        if (c < 0x1FF6) return false; if (c <= 0x1FFC) return true;
1008        if (c == 0x2126) return true;
1009        if (c < 0x212A) return false; if (c <= 0x212B) return true;
1010        if (c == 0x212E) return true;
1011        if (c < 0x2180) return false; if (c <= 0x2182) return true;
1012        if (c == 0x3007) return true; // ideographic
1013
if (c < 0x3021) return false; if (c <= 0x3029) return true; // ideo
1014
if (c < 0x3041) return false; if (c <= 0x3094) return true;
1015        if (c < 0x30A1) return false; if (c <= 0x30FA) return true;
1016        if (c < 0x3105) return false; if (c <= 0x312C) return true;
1017        if (c < 0x4E00) return false; if (c <= 0x9FA5) return true; // ideo
1018
if (c < 0xAC00) return false; if (c <= 0xD7A3) return true;
1019      
1020        return false;
1021        
1022    }
1023
1024    /**
1025     * This is a utility function for determining whether a specified character
1026     * is a combining character according to production 87
1027     * of the XML 1.0 specification.
1028     *
1029     * @param c <code>char</code> to check.
1030     * @return <code>boolean</code> true if it's a combining character,
1031     * false otherwise.
1032     */

1033    public static boolean isXMLCombiningChar(char c) {
1034        // CombiningChar
1035
if (c < 0x0300) return false; if (c <= 0x0345) return true;
1036        if (c < 0x0360) return false; if (c <= 0x0361) return true;
1037        if (c < 0x0483) return false; if (c <= 0x0486) return true;
1038        if (c < 0x0591) return false; if (c <= 0x05A1) return true;
1039                                       
1040        if (c < 0x05A3) return false; if (c <= 0x05B9) return true;
1041        if (c < 0x05BB) return false; if (c <= 0x05BD) return true;
1042        if (c == 0x05BF) return true;
1043        if (c < 0x05C1) return false; if (c <= 0x05C2) return true;
1044                                       
1045        if (c == 0x05C4) return true;
1046        if (c < 0x064B) return false; if (c <= 0x0652) return true;
1047        if (c == 0x0670) return true;
1048        if (c < 0x06D6) return false; if (c <= 0x06DC) return true;
1049                                       
1050        if (c < 0x06DD) return false; if (c <= 0x06DF) return true;
1051        if (c < 0x06E0) return false; if (c <= 0x06E4) return true;
1052        if (c < 0x06E7) return false; if (c <= 0x06E8) return true;
1053                                       
1054        if (c < 0x06EA) return false; if (c <= 0x06ED) return true;
1055        if (c < 0x0901) return false; if (c <= 0x0903) return true;
1056        if (c == 0x093C) return true;
1057        if (c < 0x093E) return false; if (c <= 0x094C) return true;
1058                                       
1059        if (c == 0x094D) return true;
1060        if (c < 0x0951) return false; if (c <= 0x0954) return true;
1061        if (c < 0x0962) return false; if (c <= 0x0963) return true;
1062        if (c < 0x0981) return false; if (c <= 0x0983) return true;
1063                                       
1064        if (c == 0x09BC) return true;
1065        if (c == 0x09BE) return true;
1066        if (c == 0x09BF) return true;
1067        if (c < 0x09C0) return false; if (c <= 0x09C4) return true;
1068        if (c < 0x09C7) return false; if (c <= 0x09C8) return true;
1069                                       
1070        if (c < 0x09CB) return false; if (c <= 0x09CD) return true;
1071        if (c == 0x09D7) return true;
1072        if (c < 0x09E2) return false; if (c <= 0x09E3) return true;
1073        if (c == 0x0A02) return true;
1074        if (c == 0x0A3C) return true;
1075                                       
1076        if (c == 0x0A3E) return true;
1077        if (c == 0x0A3F) return true;
1078        if (c < 0x0A40) return false; if (c <= 0x0A42) return true;
1079        if (c < 0x0A47) return false; if (c <= 0x0A48) return true;
1080                                       
1081        if (c < 0x0A4B) return false; if (c <= 0x0A4D) return true;
1082        if (c < 0x0A70) return false; if (c <= 0x0A71) return true;
1083        if (c < 0x0A81) return false; if (c <= 0x0A83) return true;
1084        if (c == 0x0ABC) return true;
1085                                       
1086        if (c < 0x0ABE) return false; if (c <= 0x0AC5) return true;
1087        if (c < 0x0AC7) return false; if (c <= 0x0AC9) return true;
1088        if (c < 0x0ACB) return false; if (c <= 0x0ACD) return true;
1089                                       
1090        if (c < 0x0B01) return false; if (c <= 0x0B03) return true;
1091        if (c == 0x0B3C) return true;
1092        if (c < 0x0B3E) return false; if (c <= 0x0B43) return true;
1093        if (c < 0x0B47) return false; if (c <= 0x0B48) return true;
1094                                       
1095        if (c < 0x0B4B) return false; if (c <= 0x0B4D) return true;
1096        if (c < 0x0B56) return false; if (c <= 0x0B57) return true;
1097        if (c < 0x0B82) return false; if (c <= 0x0B83) return true;
1098                                       
1099        if (c < 0x0BBE) return false; if (c <= 0x0BC2) return true;
1100        if (c < 0x0BC6) return false; if (c <= 0x0BC8) return true;
1101        if (c < 0x0BCA) return false; if (c <= 0x0BCD) return true;
1102        if (c == 0x0BD7) return true;
1103                                       
1104        if (c < 0x0C01) return false; if (c <= 0x0C03) return true;
1105        if (c < 0x0C3E) return false; if (c <= 0x0C44) return true;
1106        if (c < 0x0C46) return false; if (c <= 0x0C48) return true;
1107                                       
1108        if (c < 0x0C4A) return false; if (c <= 0x0C4D) return true;
1109        if (c < 0x0C55) return false; if (c <= 0x0C56) return true;
1110        if (c < 0x0C82) return false; if (c <= 0x0C83) return true;
1111                                       
1112        if (c < 0x0CBE) return false; if (c <= 0x0CC4) return true;
1113        if (c < 0x0CC6) return false; if (c <= 0x0CC8) return true;
1114        if (c < 0x0CCA) return false; if (c <= 0x0CCD) return true;
1115                                       
1116        if (c < 0x0CD5) return false; if (c <= 0x0CD6) return true;
1117        if (c < 0x0D02) return false; if (c <= 0x0D03) return true;
1118        if (c < 0x0D3E) return false; if (c <= 0x0D43) return true;
1119                                       
1120        if (c < 0x0D46) return false; if (c <= 0x0D48) return true;
1121        if (c < 0x0D4A) return false; if (c <= 0x0D4D) return true;
1122        if (c == 0x0D57) return true;
1123        if (c == 0x0E31) return true;
1124                                       
1125        if (c < 0x0E34) return false; if (c <= 0x0E3A) return true;
1126        if (c < 0x0E47) return false; if (c <= 0x0E4E) return true;
1127        if (c == 0x0EB1) return true;
1128        if (c < 0x0EB4) return false; if (c <= 0x0EB9) return true;
1129                                       
1130        if (c < 0x0EBB) return false; if (c <= 0x0EBC) return true;
1131        if (c < 0x0EC8) return false; if (c <= 0x0ECD) return true;
1132        if (c < 0x0F18) return false; if (c <= 0x0F19) return true;
1133        if (c == 0x0F35) return true;
1134                                       
1135        if (c == 0x0F37) return true;
1136        if (c == 0x0F39) return true;
1137        if (c == 0x0F3E) return true;
1138        if (c == 0x0F3F) return true;
1139        if (c < 0x0F71) return false; if (c <= 0x0F84) return true;
1140                                       
1141        if (c < 0x0F86) return false; if (c <= 0x0F8B) return true;
1142        if (c < 0x0F90) return false; if (c <= 0x0F95) return true;
1143        if (c == 0x0F97) return true;
1144        if (c < 0x0F99) return false; if (c <= 0x0FAD) return true;
1145                                       
1146        if (c < 0x0FB1) return false; if (c <= 0x0FB7) return true;
1147        if (c == 0x0FB9) return true;
1148        if (c < 0x20D0) return false; if (c <= 0x20DC) return true;
1149        if (c == 0x20E1) return true;
1150                                       
1151        if (c < 0x302A) return false; if (c <= 0x302F) return true;
1152        if (c == 0x3099) return true;
1153        if (c == 0x309A) return true;
1154        
1155        return false;
1156        
1157    }
1158    
1159    /**
1160     * This is a utility function for determining whether a specified
1161     * character is an extender according to production 88 of the XML 1.0
1162     * specification.
1163     *
1164     * @param c <code>char</code> to check.
1165     * @return <code>String</code> true if it's an extender, false otherwise.
1166     */

1167    public static boolean isXMLExtender(char c) {
1168
1169        if (c < 0x00B6) return false; // quick short circuit
1170

1171        // Extenders
1172
if (c == 0x00B7) return true;
1173        if (c == 0x02D0) return true;
1174        if (c == 0x02D1) return true;
1175        if (c == 0x0387) return true;
1176        if (c == 0x0640) return true;
1177        if (c == 0x0E46) return true;
1178        if (c == 0x0EC6) return true;
1179        if (c == 0x3005) return true;
1180                                       
1181        if (c < 0x3031) return false; if (c <= 0x3035) return true;
1182        if (c < 0x309D) return false; if (c <= 0x309E) return true;
1183        if (c < 0x30FC) return false; if (c <= 0x30FE) return true;
1184        
1185        return false;
1186        
1187    }
1188      
1189    /**
1190     * This is a utility function for determining whether a specified
1191     * Unicode character
1192     * is a digit according to production 88 of the XML 1.0 specification.
1193     *
1194     * @param c <code>char</code> to check for XML digit compliance
1195     * @return <code>boolean</code> true if it's a digit, false otherwise
1196     */

1197    public static boolean isXMLDigit(char c) {
1198      
1199        if (c < 0x0030) return false; if (c <= 0x0039) return true;
1200        if (c < 0x0660) return false; if (c <= 0x0669) return true;
1201        if (c < 0x06F0) return false; if (c <= 0x06F9) return true;
1202        if (c < 0x0966) return false; if (c <= 0x096F) return true;
1203                                       
1204        if (c < 0x09E6) return false; if (c <= 0x09EF) return true;
1205        if (c < 0x0A66) return false; if (c <= 0x0A6F) return true;
1206        if (c < 0x0AE6) return false; if (c <= 0x0AEF) return true;
1207                                       
1208        if (c < 0x0B66) return false; if (c <= 0x0B6F) return true;
1209        if (c < 0x0BE7) return false; if (c <= 0x0BEF) return true;
1210        if (c < 0x0C66) return false; if (c <= 0x0C6F) return true;
1211                                       
1212        if (c < 0x0CE6) return false; if (c <= 0x0CEF) return true;
1213        if (c < 0x0D66) return false; if (c <= 0x0D6F) return true;
1214        if (c < 0x0E50) return false; if (c <= 0x0E59) return true;
1215                                       
1216        if (c < 0x0ED0) return false; if (c <= 0x0ED9) return true;
1217        if (c < 0x0F20) return false; if (c <= 0x0F29) return true;
1218      
1219        return false;
1220    }
1221    
1222    /**
1223     * This is a utility function for determining whether a specified
1224     * Unicode character is a whitespace character according to production 3
1225     * of the XML 1.0 specification.
1226     *
1227     * @param c <code>char</code> to check for XML whitespace compliance
1228     * @return <code>boolean</code> true if it's a whitespace, false otherwise
1229     */

1230    public static boolean isXMLWhitespace(char c) {
1231        if (c==' ' || c=='\n' || c=='\t' || c=='\r' ){
1232            return true;
1233        }
1234        return false;
1235    }
1236}
1237
Popular Tags