1 5 package org.h2.tools.doc; 6 7 public class XMLParser { 8 9 public static final int ERROR = 0; 10 public static final int START_ELEMENT=1; 11 public static final int END_ELEMENT=2; 12 public static final int PROCESSING_INSTRUCTION=3; 13 public static final int CHARACTERS=4; 14 public static final int COMMENT=5; 15 public static final int SPACE=6; 16 public static final int START_DOCUMENT=7; 17 public static final int END_DOCUMENT=8; 18 public static final int ENTITY_REFERENCE=9; 19 public static final int ATTRIBUTE=10; 20 public static final int DTD=11; 21 public static final int CDATA=12; 22 public static final int NAMESPACE=13; 23 public static final int NOTATION_DECLARATION=14; 24 public static final int ENTITY_DECLARATION=15; 25 26 private String xml; 27 private int index; 28 private int eventType; 29 private String currentText; 30 private String prefix, localName; 31 private String [] attributeValues = new String [3]; 32 private int currentAttribute; 33 private boolean endElement; 34 35 public XMLParser(String xml) { 36 this.xml = xml; 37 eventType = START_DOCUMENT; 38 } 39 40 void addAttributeName(String prefix, String localName) { 41 if(attributeValues.length <= currentAttribute) { 42 String [] temp = new String [attributeValues.length * 2]; 43 System.arraycopy(attributeValues, 0, temp, 0, attributeValues.length); 44 attributeValues = temp; 45 } 46 attributeValues[currentAttribute++] = prefix; 47 attributeValues[currentAttribute++] = localName; 48 } 49 50 void addAttributeValue(String v) { 51 attributeValues[currentAttribute++] = v; 52 } 53 54 private int readChar() { 55 if (index >= xml.length()) { 56 return -1; 57 } 58 return xml.charAt(index++); 59 } 60 61 private void back() { 62 index--; 63 } 64 65 private void error(String expected) { 66 throw new Error ("expected: " + expected + " got: " + xml.substring(index)); 67 } 68 69 private void read(String chars) { 70 for (int i = 0; i < chars.length(); i++) { 71 if (readChar() != chars.charAt(i)) { 72 error(chars); 73 } 74 } 75 } 76 77 private void skipSpaces() { 78 while (index < xml.length() && xml.charAt(index) <= ' ') { 79 index++; 80 } 81 } 82 83 private void read() { 84 currentText = null; 85 currentAttribute = 0; 86 int currentStart = index; 87 int ch = readChar(); 88 if (ch < 0) { 89 eventType = END_DOCUMENT; 90 return; 91 } 92 if (ch == '<') { 93 currentStart = index; 94 ch = readChar(); 95 if (ch < 0) { 96 eventType = ERROR; 97 return; 98 } else if (ch == '?') { 99 eventType = PROCESSING_INSTRUCTION; 100 currentStart = index; 101 while (true) { 102 ch = readChar(); 103 if (ch < 0) { 104 error("?>"); 105 } 106 if (ch == '?' && readChar() == '>') { 107 break; 108 } 109 } 110 if(xml.substring(currentStart).startsWith("xml")) { 111 read(); 112 return; 113 } 114 currentText = xml.substring(currentStart, index - 1); 115 } else if (ch == '!') { 116 ch = readChar(); 117 if (ch == '-') { 118 eventType = COMMENT; 119 if (readChar() != '-') { 120 error("-"); 121 } 122 currentStart = index; 123 while (true) { 124 ch = readChar(); 125 if (ch < 0) { 126 error("-->"); 127 } 128 if (ch == '-' && readChar() == '-') { 129 read(">"); 130 break; 131 } 132 } 133 currentText = xml.substring(currentStart, index - 1); 134 } else if (ch == 'D') { 135 read("OCTYPE"); 136 eventType = DTD; 137 while (true) { 138 ch = readChar(); 139 if (ch < 0) { 140 break; 141 } 142 if (ch == '>') { 143 break; 144 } 145 } 146 } else if(ch == '[') { 147 read("CDATA["); 148 currentStart = index; 149 eventType = CHARACTERS; 150 while(true) { 151 ch = readChar(); 152 if(ch < 0) { 153 error("]]>"); 154 } else if(ch != ']') { 155 continue; 156 } 157 ch = readChar(); 158 if(ch < 0) { 159 error("]]>"); 160 } else if(ch == ']') { 161 do { 162 ch = readChar(); 163 if(ch < 0) { 164 error("]]>"); 165 } 166 } while(ch == ']'); 167 if(ch == '>') { 168 currentText = xml.substring(currentStart, index - 3); 169 break; 170 } 171 } 172 } 173 } 174 } else if(ch == '/') { 175 currentStart = index; 176 prefix = null; 177 eventType = END_ELEMENT; 178 while (true) { 179 ch = readChar(); 180 if (ch < 0) { 181 error(">"); 182 } else if(ch == ':') { 183 prefix = xml.substring(currentStart, index - 1); 184 currentStart = index + 1; 185 } else if(ch == '>') { 186 localName = xml.substring(currentStart, index - 1); 187 break; 188 } else if(ch <= ' ') { 189 localName = xml.substring(currentStart, index - 1); 190 skipSpaces(); 191 read(">"); 192 break; 193 } 194 } 195 } else { 196 prefix = null; 197 localName = null; 198 eventType = START_ELEMENT; 199 while (true) { 200 ch = readChar(); 201 if (ch < 0) { 202 error(">"); 203 } else if(ch == ':') { 204 prefix = xml.substring(currentStart, index - 1); 205 currentStart = index + 1; 206 } else if (ch <= ' ') { 207 localName = xml.substring(currentStart, index - 1); 208 readAttributeValues(); 209 ch = readChar(); 210 } 211 if (ch == '/') { 212 if(localName == null) { 213 localName = xml.substring(currentStart, index - 1); 214 } 215 read(">"); 216 endElement = true; 217 break; 218 } else if(ch == '>') { 219 if(localName == null) { 220 localName = xml.substring(currentStart, index - 1); 221 } 222 break; 223 } 224 } 225 } 226 } else { 227 eventType = CHARACTERS; 228 while (true) { 229 ch = readChar(); 230 if(ch < 0) { 231 break; 232 } else if(ch == '<') { 233 back(); 234 break; 235 } 236 } 237 currentText = xml.substring(currentStart, index); 238 } 239 } 240 241 private void readAttributeValues() { 242 while(true) { 243 int start = index; 244 int ch = readChar(); 245 if(ch < 0) { 246 error(">"); 247 } else if(ch <= ' ') { 248 continue; 249 } else if(ch == '/' || ch == '>') { 250 back(); 251 return; 252 } 253 int end; 254 int localNameStart = start; 255 while(true) { 256 end = index; 257 ch = readChar(); 258 if(ch < 0) { 259 error("="); 260 } else if(ch <= ' ') { 261 skipSpaces(); 262 ch = readChar(); 263 if(ch != '=') { 264 error("="); 265 } 266 break; 267 } else if(ch == '=') { 268 break; 269 } else if(ch == ':') { 270 localNameStart = index; 271 } 272 } 273 if(localNameStart == start) { 274 addAttributeName("", xml.substring(localNameStart, end)); 275 } else { 276 addAttributeName(xml.substring(start, localNameStart - 1), xml.substring(localNameStart, end)); 277 } 278 skipSpaces(); 279 ch = readChar(); 280 if(ch != '\"') { 281 error("\""); 282 } 283 start = index; 284 while(true) { 285 end = index; 286 ch = readChar(); 287 if(ch < 0) { 288 error("\""); 289 } else if(ch == '\"') { 290 break; 291 } 292 } 293 addAttributeValue(xml.substring(start, end)); 294 } 295 } 296 297 public boolean hasNext() { 298 return index < xml.length(); 299 } 300 301 public int next() { 302 if(endElement) { 303 endElement = false; 304 eventType = END_ELEMENT; 305 } else { 306 read(); 307 } 308 return eventType; 309 } 310 311 public int nextTag() { 312 while (true) { 313 int type = next(); 314 if (type != COMMENT && type != DTD && type != PROCESSING_INSTRUCTION) { 315 return type; 316 } 317 } 318 } 319 320 public int getEventType() { 321 return eventType; 322 } 323 324 public String getText() { 325 return currentText; 326 } 327 328 public int getAttributeCount() { 329 return currentAttribute / 3; 330 } 331 332 public String getAttributePrefix(int index) { 333 return attributeValues[index * 3]; 334 } 335 336 public String getAttributeLocalName(int index) { 337 return attributeValues[index * 3 + 1]; 338 } 339 340 public String getAttributeName(int index) { 341 String prefix = getAttributePrefix(index); 342 String localName = getAttributeLocalName(index); 343 return prefix == null || prefix.length() == 0 ? localName : prefix + ":" + localName; 344 } 345 346 public String getAttributeValue(int index) { 347 return attributeValues[index * 3 + 2]; 348 } 349 350 public String getAttributeValue(String namespaceURI, String localName) { 351 int len = getAttributeCount(); 352 for(int i=0; i<len; i ++) { 353 if(getAttributeLocalName(i).equals(localName)) { 354 return getAttributeValue(i); 355 } 356 } 357 return null; 358 } 359 360 public String getName() { 361 return prefix == null || prefix.length() == 0 ? localName : prefix + ":" + localName; 362 } 363 364 public String getLocalName() { 365 return localName; 366 } 367 368 public String getPrefix() { 369 return prefix; 370 } 371 372 public boolean isWhiteSpace() { 373 return getText().trim().length() == 0; 374 } 375 376 public String getRemaining() { 377 return xml.substring(index); 378 } 379 380 } 381 | Popular Tags |