3 // Permission is hereby granted, free of charge, to any person obtaining
4 // a copy of this software and associated documentation files (the
5 // "Software"), to deal in the Software without restriction, including
6 // without limitation the rights to use, copy, modify, merge, publish,
7 // distribute, sublicense, and/or sell copies of the Software, and to
8 // permit persons to whom the Software is furnished to do so, subject to
9 // the following conditions:
11 // The above copyright notice and this permission notice shall be
12 // included in all copies or substantial portions of the Software.
14 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24 namespace System.Xml
\r
27 /// http://www.w3.org/TR/REC-xml
\r
30 /// Includes code and Ideas from org.apache.xerces.util.XMLChar class of Xerces 2.0.1
\r
31 /// However, No surrogate support is included in this class.
\r
32 /// This class is currently public. Make it internal after testing completes
\r
34 internal class XmlChar//XmlConstructs
\r
36 internal static readonly char [] WhitespaceChars = {' ', '\n', '\t', '\r'};
38 /** Character flags. */
\r
39 internal static readonly byte [] CHARS = new byte [1 << 16];
\r
41 /** Valid character mask. */
\r
42 internal const int VALID = 0x01;
\r
44 /** Space character mask. */
\r
45 internal const int SPACE = 0x02;
\r
47 /** Name start character mask. */
\r
48 internal const int NAME_START = 0x04;
\r
50 /** Name character mask. */
\r
51 internal const int NAME = 0x08;
\r
53 /** Pubid character mask. */
\r
54 internal const int PUBID = 0x10;
\r
56 * Content character mask. Special characters are those that can
\r
57 * be considered the start of markup, such as '<' and '&'.
\r
58 * The various newline characters are considered special as well.
\r
59 * All other valid XML characters can be considered content.
\r
61 * This is an optimization for the inner loop of character scanning.
\r
63 internal const int CONTENT = 0x20;
\r
65 /** NCName start character mask. */
\r
66 internal const int NCNAME_START = 0x40;
\r
68 /** NCName character mask. */
\r
69 internal const int NCNAME = 0x80;
\r
74 // [2] Char ::= #x9 | #xA | #xD | [#x20-#xD7FF] |
\r
75 // [#xE000-#xFFFD] | [#x10000-#x10FFFF]
\r
77 int[] charRange = {
\r
78 0x0009, 0x000A, 0x000D, 0x000D, 0x0020, 0xD7FF, 0xE000, 0xFFFD,
\r
82 // [3] S ::= (#x20 | #x9 | #xD | #xA)+
\r
84 int[] spaceChar = {
\r
85 0x0020, 0x0009, 0x000D, 0x000A,
\r
89 // [4] NameChar ::= Letter | Digit | '.' | '-' | '_' | ':' |
\r
90 // CombiningChar | Extender
\r
93 0x002D, 0x002E, // '-' and '.'
\r
97 // [5] Name ::= (Letter | '_' | ':') (NameChar)*
\r
100 int[] nameStartChar = {
\r
101 0x003A, 0x005F, // ':' and '_'
\r
105 // [13] PubidChar ::= #x20 | 0xD | 0xA | [a-zA-Z0-9] | [-'()+,./:=?;!*#@$_%]
\r
108 int[] pubidChar = {
\r
109 0x000A, 0x000D, 0x0020, 0x0021, 0x0023, 0x0024, 0x0025, 0x003D,
\r
113 int[] pubidRange = {
\r
114 0x0027, 0x003B, 0x003F, 0x005A, 0x0061, 0x007A
\r
118 // [84] Letter ::= BaseChar | Ideographic
\r
121 int[] letterRange = {
\r
123 0x0041, 0x005A, 0x0061, 0x007A, 0x00C0, 0x00D6, 0x00D8, 0x00F6,
\r
124 0x00F8, 0x0131, 0x0134, 0x013E, 0x0141, 0x0148, 0x014A, 0x017E,
\r
125 0x0180, 0x01C3, 0x01CD, 0x01F0, 0x01F4, 0x01F5, 0x01FA, 0x0217,
\r
126 0x0250, 0x02A8, 0x02BB, 0x02C1, 0x0388, 0x038A, 0x038E, 0x03A1,
\r
127 0x03A3, 0x03CE, 0x03D0, 0x03D6, 0x03E2, 0x03F3, 0x0401, 0x040C,
\r
128 0x040E, 0x044F, 0x0451, 0x045C, 0x045E, 0x0481, 0x0490, 0x04C4,
\r
129 0x04C7, 0x04C8, 0x04CB, 0x04CC, 0x04D0, 0x04EB, 0x04EE, 0x04F5,
\r
130 0x04F8, 0x04F9, 0x0531, 0x0556, 0x0561, 0x0586, 0x05D0, 0x05EA,
\r
131 0x05F0, 0x05F2, 0x0621, 0x063A, 0x0641, 0x064A, 0x0671, 0x06B7,
\r
132 0x06BA, 0x06BE, 0x06C0, 0x06CE, 0x06D0, 0x06D3, 0x06E5, 0x06E6,
\r
133 0x0905, 0x0939, 0x0958, 0x0961, 0x0985, 0x098C, 0x098F, 0x0990,
\r
134 0x0993, 0x09A8, 0x09AA, 0x09B0, 0x09B6, 0x09B9, 0x09DC, 0x09DD,
\r
135 0x09DF, 0x09E1, 0x09F0, 0x09F1, 0x0A05, 0x0A0A, 0x0A0F, 0x0A10,
\r
136 0x0A13, 0x0A28, 0x0A2A, 0x0A30, 0x0A32, 0x0A33, 0x0A35, 0x0A36,
\r
137 0x0A38, 0x0A39, 0x0A59, 0x0A5C, 0x0A72, 0x0A74, 0x0A85, 0x0A8B,
\r
138 0x0A8F, 0x0A91, 0x0A93, 0x0AA8, 0x0AAA, 0x0AB0, 0x0AB2, 0x0AB3,
\r
139 0x0AB5, 0x0AB9, 0x0B05, 0x0B0C, 0x0B0F, 0x0B10, 0x0B13, 0x0B28,
\r
140 0x0B2A, 0x0B30, 0x0B32, 0x0B33, 0x0B36, 0x0B39, 0x0B5C, 0x0B5D,
\r
141 0x0B5F, 0x0B61, 0x0B85, 0x0B8A, 0x0B8E, 0x0B90, 0x0B92, 0x0B95,
\r
142 0x0B99, 0x0B9A, 0x0B9E, 0x0B9F, 0x0BA3, 0x0BA4, 0x0BA8, 0x0BAA,
\r
143 0x0BAE, 0x0BB5, 0x0BB7, 0x0BB9, 0x0C05, 0x0C0C, 0x0C0E, 0x0C10,
\r
144 0x0C12, 0x0C28, 0x0C2A, 0x0C33, 0x0C35, 0x0C39, 0x0C60, 0x0C61,
\r
145 0x0C85, 0x0C8C, 0x0C8E, 0x0C90, 0x0C92, 0x0CA8, 0x0CAA, 0x0CB3,
\r
146 0x0CB5, 0x0CB9, 0x0CE0, 0x0CE1, 0x0D05, 0x0D0C, 0x0D0E, 0x0D10,
\r
147 0x0D12, 0x0D28, 0x0D2A, 0x0D39, 0x0D60, 0x0D61, 0x0E01, 0x0E2E,
\r
148 0x0E32, 0x0E33, 0x0E40, 0x0E45, 0x0E81, 0x0E82, 0x0E87, 0x0E88,
\r
149 0x0E94, 0x0E97, 0x0E99, 0x0E9F, 0x0EA1, 0x0EA3, 0x0EAA, 0x0EAB,
\r
150 0x0EAD, 0x0EAE, 0x0EB2, 0x0EB3, 0x0EC0, 0x0EC4, 0x0F40, 0x0F47,
\r
151 0x0F49, 0x0F69, 0x10A0, 0x10C5, 0x10D0, 0x10F6, 0x1102, 0x1103,
\r
152 0x1105, 0x1107, 0x110B, 0x110C, 0x110E, 0x1112, 0x1154, 0x1155,
\r
153 0x115F, 0x1161, 0x116D, 0x116E, 0x1172, 0x1173, 0x11AE, 0x11AF,
\r
154 0x11B7, 0x11B8, 0x11BC, 0x11C2, 0x1E00, 0x1E9B, 0x1EA0, 0x1EF9,
\r
155 0x1F00, 0x1F15, 0x1F18, 0x1F1D, 0x1F20, 0x1F45, 0x1F48, 0x1F4D,
\r
156 0x1F50, 0x1F57, 0x1F5F, 0x1F7D, 0x1F80, 0x1FB4, 0x1FB6, 0x1FBC,
\r
157 0x1FC2, 0x1FC4, 0x1FC6, 0x1FCC, 0x1FD0, 0x1FD3, 0x1FD6, 0x1FDB,
\r
158 0x1FE0, 0x1FEC, 0x1FF2, 0x1FF4, 0x1FF6, 0x1FFC, 0x212A, 0x212B,
\r
159 0x2180, 0x2182, 0x3041, 0x3094, 0x30A1, 0x30FA, 0x3105, 0x312C,
\r
162 0x3021, 0x3029, 0x4E00, 0x9FA5,
\r
164 int[] letterChar = {
\r
166 0x0386, 0x038C, 0x03DA, 0x03DC, 0x03DE, 0x03E0, 0x0559, 0x06D5,
\r
167 0x093D, 0x09B2, 0x0A5E, 0x0A8D, 0x0ABD, 0x0AE0, 0x0B3D, 0x0B9C,
\r
168 0x0CDE, 0x0E30, 0x0E84, 0x0E8A, 0x0E8D, 0x0EA5, 0x0EA7, 0x0EB0,
\r
169 0x0EBD, 0x1100, 0x1109, 0x113C, 0x113E, 0x1140, 0x114C, 0x114E,
\r
170 0x1150, 0x1159, 0x1163, 0x1165, 0x1167, 0x1169, 0x1175, 0x119E,
\r
171 0x11A8, 0x11AB, 0x11BA, 0x11EB, 0x11F0, 0x11F9, 0x1F59, 0x1F5B,
\r
172 0x1F5D, 0x1FBE, 0x2126, 0x212E,
\r
178 // [87] CombiningChar ::= ...
\r
181 int[] combiningCharRange = {
\r
182 0x0300, 0x0345, 0x0360, 0x0361, 0x0483, 0x0486, 0x0591, 0x05A1,
\r
183 0x05A3, 0x05B9, 0x05BB, 0x05BD, 0x05C1, 0x05C2, 0x064B, 0x0652,
\r
184 0x06D6, 0x06DC, 0x06DD, 0x06DF, 0x06E0, 0x06E4, 0x06E7, 0x06E8,
\r
185 0x06EA, 0x06ED, 0x0901, 0x0903, 0x093E, 0x094C, 0x0951, 0x0954,
\r
186 0x0962, 0x0963, 0x0981, 0x0983, 0x09C0, 0x09C4, 0x09C7, 0x09C8,
\r
187 0x09CB, 0x09CD, 0x09E2, 0x09E3, 0x0A40, 0x0A42, 0x0A47, 0x0A48,
\r
188 0x0A4B, 0x0A4D, 0x0A70, 0x0A71, 0x0A81, 0x0A83, 0x0ABE, 0x0AC5,
\r
189 0x0AC7, 0x0AC9, 0x0ACB, 0x0ACD, 0x0B01, 0x0B03, 0x0B3E, 0x0B43,
\r
190 0x0B47, 0x0B48, 0x0B4B, 0x0B4D, 0x0B56, 0x0B57, 0x0B82, 0x0B83,
\r
191 0x0BBE, 0x0BC2, 0x0BC6, 0x0BC8, 0x0BCA, 0x0BCD, 0x0C01, 0x0C03,
\r
192 0x0C3E, 0x0C44, 0x0C46, 0x0C48, 0x0C4A, 0x0C4D, 0x0C55, 0x0C56,
\r
193 0x0C82, 0x0C83, 0x0CBE, 0x0CC4, 0x0CC6, 0x0CC8, 0x0CCA, 0x0CCD,
\r
194 0x0CD5, 0x0CD6, 0x0D02, 0x0D03, 0x0D3E, 0x0D43, 0x0D46, 0x0D48,
\r
195 0x0D4A, 0x0D4D, 0x0E34, 0x0E3A, 0x0E47, 0x0E4E, 0x0EB4, 0x0EB9,
\r
196 0x0EBB, 0x0EBC, 0x0EC8, 0x0ECD, 0x0F18, 0x0F19, 0x0F71, 0x0F84,
\r
197 0x0F86, 0x0F8B, 0x0F90, 0x0F95, 0x0F99, 0x0FAD, 0x0FB1, 0x0FB7,
\r
198 0x20D0, 0x20DC, 0x302A, 0x302F,
\r
201 int[] combiningCharChar = {
\r
202 0x05BF, 0x05C4, 0x0670, 0x093C, 0x094D, 0x09BC, 0x09BE, 0x09BF,
\r
203 0x09D7, 0x0A02, 0x0A3C, 0x0A3E, 0x0A3F, 0x0ABC, 0x0B3C, 0x0BD7,
\r
204 0x0D57, 0x0E31, 0x0EB1, 0x0F35, 0x0F37, 0x0F39, 0x0F3E, 0x0F3F,
\r
205 0x0F97, 0x0FB9, 0x20E1, 0x3099, 0x309A,
\r
209 // [88] Digit ::= ...
\r
212 int[] digitRange = {
\r
213 0x0030, 0x0039, 0x0660, 0x0669, 0x06F0, 0x06F9, 0x0966, 0x096F,
\r
214 0x09E6, 0x09EF, 0x0A66, 0x0A6F, 0x0AE6, 0x0AEF, 0x0B66, 0x0B6F,
\r
215 0x0BE7, 0x0BEF, 0x0C66, 0x0C6F, 0x0CE6, 0x0CEF, 0x0D66, 0x0D6F,
\r
216 0x0E50, 0x0E59, 0x0ED0, 0x0ED9, 0x0F20, 0x0F29,
\r
220 // [89] Extender ::= ...
\r
223 int[] extenderRange = {
\r
224 0x3031, 0x3035, 0x309D, 0x309E, 0x30FC, 0x30FE,
\r
227 int[] extenderChar = {
\r
228 0x00B7, 0x02D0, 0x02D1, 0x0387, 0x0640, 0x0E46, 0x0EC6, 0x3005,
\r
232 // SpecialChar ::= '<', '&', '\n', '\r', ']'
\r
235 int[] specialChar = {
\r
236 '<', '&', '\n', '\r', ']',
\r
243 // set valid characters
\r
244 for (int i = 0; i < charRange.Length; i += 2)
\r
246 for (int j = charRange[i]; j <= charRange[i + 1]; j++)
\r
248 CHARS[j] = (byte)(CHARS[j] | VALID | CONTENT);
\r
252 // remove special characters
\r
253 for (int i = 0; i < specialChar.Length; i++)
\r
255 CHARS[specialChar[i]] = (byte)(CHARS[specialChar[i]] & ~CONTENT);
\r
258 // set space characters
\r
259 for (int i = 0; i < spaceChar.Length; i++)
\r
261 CHARS[spaceChar[i]] = (byte)(CHARS[spaceChar[i]] | SPACE);
\r
264 // set name start characters
\r
265 for (int i = 0; i < nameStartChar.Length; i++)
\r
267 CHARS[nameStartChar[i]] = (byte)(CHARS[nameStartChar[i]] | NAME_START | NAME |
\r
268 NCNAME_START | NCNAME);
\r
270 for (int i = 0; i < letterRange.Length; i += 2)
\r
272 for (int j = letterRange[i]; j <= letterRange[i + 1]; j++)
\r
274 CHARS[j] = (byte)(CHARS[j] | NAME_START | NAME | NCNAME_START | NCNAME);
\r
277 for (int i = 0; i < letterChar.Length; i++)
\r
279 CHARS[letterChar[i]] = (byte)(CHARS[letterChar[i]] | NAME_START | NAME |
\r
280 NCNAME_START | NCNAME);
\r
283 // set name characters
\r
284 for (int i = 0; i < nameChar.Length; i++)
\r
286 CHARS[nameChar[i]] = (byte)(CHARS[nameChar[i]] | NAME | NCNAME);
\r
288 for (int i = 0; i < digitRange.Length; i += 2)
\r
290 for (int j = digitRange[i]; j <= digitRange[i + 1]; j++)
\r
292 CHARS[j] = (byte)(CHARS[j] | NAME | NCNAME);
\r
295 for (int i = 0; i < combiningCharRange.Length; i += 2)
\r
297 for (int j = combiningCharRange[i]; j <= combiningCharRange[i + 1]; j++)
\r
299 CHARS[j] = (byte)(CHARS[j] | NAME | NCNAME);
\r
302 for (int i = 0; i < combiningCharChar.Length; i++)
\r
304 CHARS[combiningCharChar[i]] = (byte)(CHARS[combiningCharChar[i]] | NAME | NCNAME);
\r
306 for (int i = 0; i < extenderRange.Length; i += 2)
\r
308 for (int j = extenderRange[i]; j <= extenderRange[i + 1]; j++)
\r
310 CHARS[j] = (byte)(CHARS[j] | NAME | NCNAME);
\r
313 for (int i = 0; i < extenderChar.Length; i++)
\r
315 CHARS[extenderChar[i]] = (byte)(CHARS[extenderChar[i]] | NAME | NCNAME);
\r
318 // remove ':' from allowable NCNAME_START and NCNAME chars
\r
319 CHARS[':'] = (byte)(CHARS[':'] & ~(NCNAME_START | NCNAME));
\r
321 // set Pubid characters
\r
322 for (int i = 0; i < pubidChar.Length; i++)
\r
324 CHARS[pubidChar[i]] = (byte)(CHARS[pubidChar[i]] | PUBID);
\r
326 for (int i = 0; i < pubidRange.Length; i += 2)
\r
328 for (int j = pubidRange[i]; j <= pubidRange[i + 1]; j++)
\r
330 CHARS[j] = (byte)(CHARS[j] | PUBID);
\r
343 /// Returns true if the specified character is valid.
\r
345 /// <param name="c">The character to check.</param>
\r
346 public static bool IsValid(char c)
\r
348 return c > 0 && ((CHARS[c] & VALID) != 0);
\r
351 public static bool IsValid (int c)
\r
354 return c < 0x110000;
\r
355 return c > 0 && ((CHARS[c] & VALID) != 0);
\r
359 /// Returns true if the specified character is invalid.
\r
361 /// <param name="c">The character to check.</param>
\r
362 public static bool IsInvalid(char c)
\r
364 return !IsValid(c);
\r
367 public static bool IsInvalid(int c)
\r
369 return !IsValid(c);
\r
373 /// Returns true if the specified character can be considered content.
\r
375 /// <param name="c">The character to check.</param>
\r
376 public static bool IsContent(char c)
\r
378 return (CHARS[c] & CONTENT) != 0;
\r
381 public static bool IsContent(int c)
\r
383 return c > 0 && c < CHARS.Length && (CHARS[c] & CONTENT) != 0;
\r
387 /// Returns true if the specified character can be considered markup.
\r
388 /// Markup characters include '<', '&', and '%'.
\r
390 /// <param name="c">The character to check.</param>
\r
391 public static bool IsMarkup(char c)
\r
393 return c == '<' || c == '&' || c == '%';
\r
396 public static bool IsMarkup(int c)
\r
398 return c > 0 && c < CHARS.Length && (c == '<' || c == '&' || c == '%');
\r
402 /// Returns true if the specified character is a space character
\r
403 /// as defined by production [3] in the XML 1.0 specification.
\r
405 /// <param name="c">The character to check.</param>
\r
406 /// <returns></returns>
\r
407 public static bool IsWhitespace (char c)
\r
409 return (CHARS[c] & SPACE) != 0;
\r
412 public static bool IsWhitespace (int c)
\r
414 return c > 0 && c < CHARS.Length && (CHARS[c] & SPACE) != 0;
\r
418 /// Returns true if the specified character is a valid name start
\r
419 /// character as defined by production [5] in the XML 1.0 specification.
\r
421 /// <param name="c">The character to check.</param>
\r
422 public static bool IsFirstNameChar (char c)
\r
424 return (CHARS[c] & NAME_START) != 0;
\r
427 public static bool IsFirstNameChar (int c)
\r
429 return c > 0 && c < CHARS.Length && (CHARS[c] & NAME_START) != 0;
\r
433 /// Returns true if the specified character is a valid name
\r
434 /// character as defined by production [4] in the XML 1.0 specification.
\r
436 /// <param name="c">The character to check.</param>
\r
437 public static bool IsNameChar(char c)
\r
439 return (CHARS[c] & NAME) != 0;
\r
442 public static bool IsNameChar(int c)
\r
444 return c > 0 && c < CHARS.Length && (CHARS[c] & NAME) != 0;
\r
448 /// Returns true if the specified character is a valid NCName start
\r
449 /// character as defined by production [4] in Namespaces in XML
\r
450 /// recommendation.
\r
452 /// <param name="c">The character to check.</param>
\r
453 /// <returns></returns>
\r
454 public static bool IsNCNameStart(char c)
\r
456 return (CHARS[c] & NCNAME_START) != 0;
\r
459 public static bool IsNCNameStart(int c)
\r
461 return c > 0 && c < CHARS.Length && (CHARS[c] & NCNAME_START) != 0;
\r
465 /// Returns true if the specified character is a valid NCName
\r
466 /// character as defined by production [5] in Namespaces in XML
\r
467 /// recommendation.
\r
469 /// <param name="c"></param>
\r
470 /// <returns></returns>
\r
471 public static bool IsNCNameChar(char c)
\r
473 return (CHARS[c] & NCNAME) != 0;
\r
476 public static bool IsNCNameChar(int c)
\r
478 return c > 0 && c < CHARS.Length && (CHARS[c] & NCNAME) != 0;
\r
482 /// Returns true if the specified character is a valid Pubid
\r
483 /// character as defined by production [13] in the XML 1.0 specification.
\r
485 /// <param name="c">The character to check</param>
\r
486 public static bool IsPubidChar (char c)
\r
488 return (CHARS[c] & PUBID) != 0;
\r
491 public static bool IsPubidChar (int c)
\r
493 return c > 0 && c < CHARS.Length && (CHARS[c] & PUBID) != 0;
\r
497 /// Check to see if a string is a valid Name according to [5]
\r
498 /// in the XML 1.0 Recommendation
\r
500 /// <param name="name">The string to check</param>
\r
501 public static bool IsValidName(String name, out Exception err)
\r
504 if (name.Length == 0)
\r
506 err = new XmlException("Name can not be an empty string",null);
\r
510 if( IsFirstNameChar (ch) == false)
\r
512 err = new XmlException("The character '"+ch+"' cannot start a Name",null);
\r
515 for (int i = 1; i < name.Length; i++ )
\r
518 if( IsNameChar (ch) == false )
\r
520 err = new XmlException("The character '"+ch+"' is not allowed in a Name",null);
\r
527 public static int IsValidName (string name)
\r
529 if (name.Length == 0)
\r
531 if (!IsFirstNameChar (name [0]))
\r
533 for (int i=1; i<name.Length; i++)
\r
534 if (!IsNameChar (name [i]))
\r
540 /// Check to see if a string is a valid NCName according to [4]
\r
541 /// from the XML Namespaces 1.0 Recommendation
\r
543 /// <param name="ncName">The string to check</param>
\r
544 public static bool IsValidNCName(String ncName, out Exception err)
\r
547 if (ncName.Length == 0)
\r
549 err = new XmlException("NCName can not be an empty string",null);
\r
552 char ch = ncName[0];
\r
553 if( IsNCNameStart(ch) == false)
\r
555 err = new XmlException("The character '"+ch+"' cannot start a NCName",null);
\r
558 for (int i = 1; i < ncName.Length; i++ )
\r
561 if( IsNCNameChar (ch) == false )
\r
563 err = new XmlException("The character '"+ch+"' is not allowed in a NCName",null);
\r
571 /// Check to see if a string is a valid Nmtoken according to [7]
\r
572 /// in the XML 1.0 Recommendation
\r
574 /// <param name="nmtoken">The string to check.</param>
\r
575 public static bool IsValidNmtoken(String nmtoken, out Exception err)
\r
578 if (nmtoken.Length == 0)
\r
580 err = new XmlException("NMTOKEN can not be an empty string", null);
\r
583 for (int i = 0; i < nmtoken.Length; i++ )
\r
585 char ch = nmtoken[i];
\r
586 if( ! IsNameChar (ch) )
\r
588 err = new XmlException("The character '"+ch+"' is not allowed in a NMTOKEN",null);
\r
598 /// Returns true if the encoding name is a valid IANA encoding.
\r
599 /// This method does not verify that there is a decoder available
\r
600 /// for this encoding, only that the characters are valid for an
\r
601 /// IANA encoding name.
\r
603 /// <param name="ianaEncoding">The encoding to check.</param>
\r
604 /// <returns></returns>
\r
605 public static bool IsValidIANAEncoding(String ianaEncoding)
\r
607 if (ianaEncoding != null)
\r
609 int length = ianaEncoding.Length;
\r
612 char c = ianaEncoding[0];
\r
613 if ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z'))
\r
615 for (int i = 1; i < length; i++)
\r
617 c = ianaEncoding[i];
\r
618 if ((c < 'A' || c > 'Z') && (c < 'a' || c > 'z') &&
\r
619 (c < '0' || c > '9') && c != '.' && c != '_' &&
\r
632 public static bool IsName (string str)
\r
634 if (str.Length == 0)
\r
636 if (!IsFirstNameChar (str [0]))
\r
638 for (int i = 1; i < str.Length; i++)
\r
639 if (!IsNameChar (str [i]))
\r
644 public static bool IsNCName (string str)
\r
646 if (str.Length == 0)
\r
648 if (!IsFirstNameChar (str [0]))
\r
650 for (int i = 0; i < str.Length; i++)
\r
651 if (!IsNCNameChar (str [i]))
\r
656 public static bool IsNmToken (string str)
\r
658 if (str.Length == 0)
\r
660 for (int i = 0; i < str.Length; i++)
\r
661 if (!IsNameChar (str [i]))
\r
666 public static bool IsWhitespace (string str)
\r
668 for (int i = 0; i < str.Length; i++)
669 if (!IsWhitespace (str [i])) return false;
674 public static int GetPredefinedEntity (string name)
\r