1 // line 1 "XmlReader.rl" 2 // Do not edit this file! Generated by Ragel. 3 // Ragel.exe -G2 -J -o XmlReader.java XmlReader.rl 4 /******************************************************************************* 5 * Copyright 2011 See AUTHORS file. 6 * 7 * Licensed under the Apache License, Version 2.0 (the "License"); 8 * you may not use this file except in compliance with the License. 9 * You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, software 14 * distributed under the License is distributed on an "AS IS" BASIS, 15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 * See the License for the specific language governing permissions and 17 * limitations under the License. 18 ******************************************************************************/ 19 20 package com.badlogic.gdx.utils; 21 22 import java.io.IOException; 23 import java.io.InputStream; 24 import java.io.InputStreamReader; 25 import java.io.Reader; 26 27 import com.badlogic.gdx.files.FileHandle; 28 import com.badlogic.gdx.utils.ObjectMap.Entry; 29 30 /** Lightweight XML parser. Supports a subset of XML features: elements, attributes, text, predefined entities, CDATA, mixed 31 * content. Namespaces are parsed as part of the element or attribute name. Prologs and doctypes are ignored. Only 8-bit character 32 * encodings are supported. Input is assumed to be well formed.<br> 33 * <br> 34 * The default behavior is to parse the XML into a DOM. Extends this class and override methods to perform event driven parsing. 35 * When this is done, the parse methods will return null. 36 * @author Nathan Sweet */ 37 public class XmlReader { 38 private final Array<Element> elements = new Array(8); 39 private Element root, current; 40 private final StringBuilder textBuffer = new StringBuilder(64); 41 42 public Element parse (String xml) { 43 char[] data = xml.toCharArray(); 44 return parse(data, 0, data.length); 45 } 46 47 public Element parse (Reader reader) throws IOException { 48 try { 49 char[] data = new char[1024]; 50 int offset = 0; 51 while (true) { 52 int length = reader.read(data, offset, data.length - offset); 53 if (length == -1) break; 54 if (length == 0) { 55 char[] newData = new char[data.length * 2]; 56 System.arraycopy(data, 0, newData, 0, data.length); 57 data = newData; 58 } else 59 offset += length; 60 } 61 return parse(data, 0, offset); 62 } catch (IOException ex) { 63 throw new SerializationException(ex); 64 } finally { 65 StreamUtils.closeQuietly(reader); 66 } 67 } 68 69 public Element parse (InputStream input) throws IOException { 70 try { 71 return parse(new InputStreamReader(input, "UTF-8")); 72 } catch (IOException ex) { 73 throw new SerializationException(ex); 74 } finally { 75 StreamUtils.closeQuietly(input); 76 } 77 } 78 79 public Element parse (FileHandle file) throws IOException { 80 try { 81 return parse(file.reader("UTF-8")); 82 } catch (Exception ex) { 83 throw new SerializationException("Error parsing file: " + file, ex); 84 } 85 } 86 87 public Element parse (char[] data, int offset, int length) { 88 int cs, p = offset, pe = length; 89 90 int s = 0; 91 String attributeName = null; 92 boolean hasBody = false; 93 94 // line 93 "XmlReader.java" 95 { 96 cs = xml_start; 97 } 98 99 // line 97 "XmlReader.java" 100 { 101 int _klen; 102 int _trans = 0; 103 int _acts; 104 int _nacts; 105 int _keys; 106 int _goto_targ = 0; 107 108 _goto: 109 while (true) { 110 switch (_goto_targ) { 111 case 0: 112 if (p == pe) { 113 _goto_targ = 4; 114 continue _goto; 115 } 116 if (cs == 0) { 117 _goto_targ = 5; 118 continue _goto; 119 } 120 case 1: 121 _match: 122 do { 123 _keys = _xml_key_offsets[cs]; 124 _trans = _xml_index_offsets[cs]; 125 _klen = _xml_single_lengths[cs]; 126 if (_klen > 0) { 127 int _lower = _keys; 128 int _mid; 129 int _upper = _keys + _klen - 1; 130 while (true) { 131 if (_upper < _lower) break; 132 133 _mid = _lower + ((_upper - _lower) >> 1); 134 if (data[p] < _xml_trans_keys[_mid]) 135 _upper = _mid - 1; 136 else if (data[p] > _xml_trans_keys[_mid]) 137 _lower = _mid + 1; 138 else { 139 _trans += (_mid - _keys); 140 break _match; 141 } 142 } 143 _keys += _klen; 144 _trans += _klen; 145 } 146 147 _klen = _xml_range_lengths[cs]; 148 if (_klen > 0) { 149 int _lower = _keys; 150 int _mid; 151 int _upper = _keys + (_klen << 1) - 2; 152 while (true) { 153 if (_upper < _lower) break; 154 155 _mid = _lower + (((_upper - _lower) >> 1) & ~1); 156 if (data[p] < _xml_trans_keys[_mid]) 157 _upper = _mid - 2; 158 else if (data[p] > _xml_trans_keys[_mid + 1]) 159 _lower = _mid + 2; 160 else { 161 _trans += ((_mid - _keys) >> 1); 162 break _match; 163 } 164 } 165 _trans += _klen; 166 } 167 } while (false); 168 169 _trans = _xml_indicies[_trans]; 170 cs = _xml_trans_targs[_trans]; 171 172 if (_xml_trans_actions[_trans] != 0) { 173 _acts = _xml_trans_actions[_trans]; 174 _nacts = (int)_xml_actions[_acts++]; 175 while (_nacts-- > 0) { 176 switch (_xml_actions[_acts++]) { 177 case 0: 178 // line 94 "XmlReader.rl" 179 { 180 s = p; 181 } 182 break; 183 case 1: 184 // line 95 "XmlReader.rl" 185 { 186 char c = data[s]; 187 if (c == '?' || c == '!') { 188 if (data[s + 1] == '[' && // 189 data[s + 2] == 'C' && // 190 data[s + 3] == 'D' && // 191 data[s + 4] == 'A' && // 192 data[s + 5] == 'T' && // 193 data[s + 6] == 'A' && // 194 data[s + 7] == '[') { 195 s += 8; 196 p = s + 2; 197 while (data[p - 2] != ']' || data[p - 1] != ']' || data[p] != '>') 198 p++; 199 text(new String(data, s, p - s - 2)); 200 } else if (c == '!' && data[s + 1] == '-' && data[s + 2] == '-') { 201 p = s + 3; 202 while (data[p] != '-' || data[p + 1] != '-' || data[p + 2] != '>') 203 p++; 204 p += 2; 205 } else 206 while (data[p] != '>') 207 p++; 208 { 209 cs = 15; 210 _goto_targ = 2; 211 if (true) continue _goto; 212 } 213 } 214 hasBody = true; 215 open(new String(data, s, p - s)); 216 } 217 break; 218 case 2: 219 // line 125 "XmlReader.rl" 220 { 221 hasBody = false; 222 close(); 223 { 224 cs = 15; 225 _goto_targ = 2; 226 if (true) continue _goto; 227 } 228 } 229 break; 230 case 3: 231 // line 130 "XmlReader.rl" 232 { 233 close(); 234 { 235 cs = 15; 236 _goto_targ = 2; 237 if (true) continue _goto; 238 } 239 } 240 break; 241 case 4: 242 // line 134 "XmlReader.rl" 243 { 244 if (hasBody) { 245 cs = 15; 246 _goto_targ = 2; 247 if (true) continue _goto; 248 } 249 } 250 break; 251 case 5: 252 // line 137 "XmlReader.rl" 253 { 254 attributeName = new String(data, s, p - s); 255 } 256 break; 257 case 6: 258 // line 140 "XmlReader.rl" 259 { 260 attribute(attributeName, new String(data, s, p - s)); 261 } 262 break; 263 case 7: 264 // line 143 "XmlReader.rl" 265 { 266 int end = p; 267 while (end != s) { 268 switch (data[end - 1]) { 269 case ' ': 270 case '\t': 271 case '\n': 272 case '\r': 273 end--; 274 continue; 275 } 276 break; 277 } 278 int current = s; 279 boolean entityFound = false; 280 while (current != end) { 281 if (data[current++] != '&') continue; 282 int entityStart = current; 283 while (current != end) { 284 if (data[current++] != ';') continue; 285 textBuffer.append(data, s, entityStart - s - 1); 286 String name = new String(data, entityStart, current - entityStart - 1); 287 String value = entity(name); 288 textBuffer.append(value != null ? value : name); 289 s = current; 290 entityFound = true; 291 break; 292 } 293 } 294 if (entityFound) { 295 if (s < end) textBuffer.append(data, s, end - s); 296 text(textBuffer.toString()); 297 textBuffer.setLength(0); 298 } else 299 text(new String(data, s, end - s)); 300 } 301 break; 302 // line 286 "XmlReader.java" 303 } 304 } 305 } 306 307 case 2: 308 if (cs == 0) { 309 _goto_targ = 5; 310 continue _goto; 311 } 312 if (++p != pe) { 313 _goto_targ = 1; 314 continue _goto; 315 } 316 case 4: 317 case 5: 318 } 319 break; 320 } 321 } 322 323 // line 190 "XmlReader.rl" 324 325 if (p < pe) { 326 int lineNumber = 1; 327 for (int i = 0; i < p; i++) 328 if (data[i] == '\n') lineNumber++; 329 throw new SerializationException("Error parsing XML on line " + lineNumber + " near: " 330 + new String(data, p, Math.min(32, pe - p))); 331 } else if (elements.size != 0) { 332 Element element = elements.peek(); 333 elements.clear(); 334 throw new SerializationException("Error parsing XML, unclosed element: " + element.getName()); 335 } 336 Element root = this.root; 337 this.root = null; 338 return root; 339 } 340 341 // line 324 "XmlReader.java" 342 private static byte[] init__xml_actions_0 () { 343 return new byte[] {0, 1, 0, 1, 1, 1, 2, 1, 3, 1, 4, 1, 5, 1, 6, 1, 7, 2, 0, 6, 2, 1, 4, 2, 2, 4}; 344 } 345 346 private static final byte _xml_actions[] = init__xml_actions_0(); 347 348 private static byte[] init__xml_key_offsets_0 () { 349 return new byte[] {0, 0, 4, 9, 14, 20, 26, 30, 35, 36, 37, 42, 46, 50, 51, 52, 56, 57, 62, 67, 73, 79, 83, 88, 89, 90, 95, 350 99, 103, 104, 108, 109, 110, 111, 112, 115}; 351 } 352 353 private static final byte _xml_key_offsets[] = init__xml_key_offsets_0(); 354 355 private static char[] init__xml_trans_keys_0 () { 356 return new char[] {32, 60, 9, 13, 32, 47, 62, 9, 13, 32, 47, 62, 9, 13, 32, 47, 61, 62, 9, 13, 32, 47, 61, 62, 9, 13, 32, 357 61, 9, 13, 32, 34, 39, 9, 13, 34, 34, 32, 47, 62, 9, 13, 32, 62, 9, 13, 32, 62, 9, 13, 39, 39, 32, 60, 9, 13, 60, 32, 358 47, 62, 9, 13, 32, 47, 62, 9, 13, 32, 47, 61, 62, 9, 13, 32, 47, 61, 62, 9, 13, 32, 61, 9, 13, 32, 34, 39, 9, 13, 34, 359 34, 32, 47, 62, 9, 13, 32, 62, 9, 13, 32, 62, 9, 13, 60, 32, 47, 9, 13, 62, 62, 39, 39, 32, 9, 13, 0}; 360 } 361 362 private static final char _xml_trans_keys[] = init__xml_trans_keys_0(); 363 364 private static byte[] init__xml_single_lengths_0 () { 365 return new byte[] {0, 2, 3, 3, 4, 4, 2, 3, 1, 1, 3, 2, 2, 1, 1, 2, 1, 3, 3, 4, 4, 2, 3, 1, 1, 3, 2, 2, 1, 2, 1, 1, 1, 1, 1, 366 0}; 367 } 368 369 private static final byte _xml_single_lengths[] = init__xml_single_lengths_0(); 370 371 private static byte[] init__xml_range_lengths_0 () { 372 return new byte[] {0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 0, 1, 0, 0, 0, 0, 1, 373 0}; 374 } 375 376 private static final byte _xml_range_lengths[] = init__xml_range_lengths_0(); 377 378 private static short[] init__xml_index_offsets_0 () { 379 return new short[] {0, 0, 4, 9, 14, 20, 26, 30, 35, 37, 39, 44, 48, 52, 54, 56, 60, 62, 67, 72, 78, 84, 88, 93, 95, 97, 380 102, 106, 110, 112, 116, 118, 120, 122, 124, 127}; 381 } 382 383 private static final short _xml_index_offsets[] = init__xml_index_offsets_0(); 384 385 private static byte[] init__xml_indicies_0 () { 386 return new byte[] {0, 2, 0, 1, 2, 1, 1, 2, 3, 5, 6, 7, 5, 4, 9, 10, 1, 11, 9, 8, 13, 1, 14, 1, 13, 12, 15, 16, 15, 1, 16, 387 17, 18, 16, 1, 20, 19, 22, 21, 9, 10, 11, 9, 1, 23, 24, 23, 1, 25, 11, 25, 1, 20, 26, 22, 27, 29, 30, 29, 28, 32, 31, 388 30, 34, 1, 30, 33, 36, 37, 38, 36, 35, 40, 41, 1, 42, 40, 39, 44, 1, 45, 1, 44, 43, 46, 47, 46, 1, 47, 48, 49, 47, 1, 389 51, 50, 53, 52, 40, 41, 42, 40, 1, 54, 55, 54, 1, 56, 42, 56, 1, 57, 1, 57, 34, 57, 1, 1, 58, 59, 58, 51, 60, 53, 61, 390 62, 62, 1, 1, 0}; 391 } 392 393 private static final byte _xml_indicies[] = init__xml_indicies_0(); 394 395 private static byte[] init__xml_trans_targs_0 () { 396 return new byte[] {1, 0, 2, 3, 3, 4, 11, 34, 5, 4, 11, 34, 5, 6, 7, 6, 7, 8, 13, 9, 10, 9, 10, 12, 34, 12, 14, 14, 16, 15, 397 17, 16, 17, 18, 30, 18, 19, 26, 28, 20, 19, 26, 28, 20, 21, 22, 21, 22, 23, 32, 24, 25, 24, 25, 27, 28, 27, 29, 31, 35, 398 33, 33, 34}; 399 } 400 401 private static final byte _xml_trans_targs[] = init__xml_trans_targs_0(); 402 403 private static byte[] init__xml_trans_actions_0 () { 404 return new byte[] {0, 0, 0, 1, 0, 3, 3, 20, 1, 0, 0, 9, 0, 11, 11, 0, 0, 0, 0, 1, 17, 0, 13, 5, 23, 0, 1, 0, 1, 0, 0, 0, 405 15, 1, 0, 0, 3, 3, 20, 1, 0, 0, 9, 0, 11, 11, 0, 0, 0, 0, 1, 17, 0, 13, 5, 23, 0, 0, 0, 7, 1, 0, 0}; 406 } 407 408 private static final byte _xml_trans_actions[] = init__xml_trans_actions_0(); 409 410 static final int xml_start = 1; 411 static final int xml_first_final = 34; 412 static final int xml_error = 0; 413 414 static final int xml_en_elementBody = 15; 415 static final int xml_en_main = 1; 416 417 // line 209 "XmlReader.rl" 418 419 protected void open (String name) { 420 Element child = new Element(name, current); 421 Element parent = current; 422 if (parent != null) parent.addChild(child); 423 elements.add(child); 424 current = child; 425 } 426 427 protected void attribute (String name, String value) { 428 current.setAttribute(name, value); 429 } 430 431 protected String entity (String name) { 432 if (name.equals("lt")) return "<"; 433 if (name.equals("gt")) return ">"; 434 if (name.equals("amp")) return "&"; 435 if (name.equals("apos")) return "'"; 436 if (name.equals("quot")) return "\""; 437 if (name.startsWith("#x")) return Character.toString((char)Integer.parseInt(name.substring(2), 16)); 438 return null; 439 } 440 441 protected void text (String text) { 442 String existing = current.getText(); 443 current.setText(existing != null ? existing + text : text); 444 } 445 446 protected void close () { 447 root = elements.pop(); 448 current = elements.size > 0 ? elements.peek() : null; 449 } 450 451 static public class Element { 452 private final String name; 453 private ObjectMap<String, String> attributes; 454 private Array<Element> children; 455 private String text; 456 private Element parent; 457 458 public Element (String name, Element parent) { 459 this.name = name; 460 this.parent = parent; 461 } 462 463 public String getName () { 464 return name; 465 } 466 467 public ObjectMap<String, String> getAttributes () { 468 return attributes; 469 } 470 471 /** @throws GdxRuntimeException if the attribute was not found. */ 472 public String getAttribute (String name) { 473 if (attributes == null) throw new GdxRuntimeException("Element " + name + " doesn't have attribute: " + name); 474 String value = attributes.get(name); 475 if (value == null) throw new GdxRuntimeException("Element " + name + " doesn't have attribute: " + name); 476 return value; 477 } 478 479 public String getAttribute (String name, String defaultValue) { 480 if (attributes == null) return defaultValue; 481 String value = attributes.get(name); 482 if (value == null) return defaultValue; 483 return value; 484 } 485 486 public void setAttribute (String name, String value) { 487 if (attributes == null) attributes = new ObjectMap(8); 488 attributes.put(name, value); 489 } 490 491 public int getChildCount () { 492 if (children == null) return 0; 493 return children.size; 494 } 495 496 /** @throws GdxRuntimeException if the element has no children. */ 497 public Element getChild (int index) { 498 if (children == null) throw new GdxRuntimeException("Element has no children: " + name); 499 return children.get(index); 500 } 501 502 public void addChild (Element element) { 503 if (children == null) children = new Array(8); 504 children.add(element); 505 } 506 507 public String getText () { 508 return text; 509 } 510 511 public void setText (String text) { 512 this.text = text; 513 } 514 515 public void removeChild (int index) { 516 if (children != null) children.removeIndex(index); 517 } 518 519 public void removeChild (Element child) { 520 if (children != null) children.removeValue(child, true); 521 } 522 523 public void remove () { 524 parent.removeChild(this); 525 } 526 527 public Element getParent () { 528 return parent; 529 } 530 531 public String toString () { 532 return toString(""); 533 } 534 535 public String toString (String indent) { 536 StringBuilder buffer = new StringBuilder(128); 537 buffer.append(indent); 538 buffer.append('<'); 539 buffer.append(name); 540 if (attributes != null) { 541 for (Entry<String, String> entry : attributes.entries()) { 542 buffer.append(' '); 543 buffer.append(entry.key); 544 buffer.append("=\""); 545 buffer.append(entry.value); 546 buffer.append('\"'); 547 } 548 } 549 if (children == null && (text == null || text.length() == 0)) 550 buffer.append("/>"); 551 else { 552 buffer.append(">\n"); 553 String childIndent = indent + '\t'; 554 if (text != null && text.length() > 0) { 555 buffer.append(childIndent); 556 buffer.append(text); 557 buffer.append('\n'); 558 } 559 if (children != null) { 560 for (Element child : children) { 561 buffer.append(child.toString(childIndent)); 562 buffer.append('\n'); 563 } 564 } 565 buffer.append(indent); 566 buffer.append("</"); 567 buffer.append(name); 568 buffer.append('>'); 569 } 570 return buffer.toString(); 571 } 572 573 /** @param name the name of the child {@link Element} 574 * @return the first child having the given name or null, does not recurse */ 575 public Element getChildByName (String name) { 576 if (children == null) return null; 577 for (int i = 0; i < children.size; i++) { 578 Element element = children.get(i); 579 if (element.name.equals(name)) return element; 580 } 581 return null; 582 } 583 584 /** @param name the name of the child {@link Element} 585 * @return the first child having the given name or null, recurses */ 586 public Element getChildByNameRecursive (String name) { 587 if (children == null) return null; 588 for (int i = 0; i < children.size; i++) { 589 Element element = children.get(i); 590 if (element.name.equals(name)) return element; 591 Element found = element.getChildByNameRecursive(name); 592 if (found != null) return found; 593 } 594 return null; 595 } 596 597 /** @param name the name of the children 598 * @return the children with the given name or an empty {@link Array} */ 599 public Array<Element> getChildrenByName (String name) { 600 Array<Element> result = new Array<Element>(); 601 if (children == null) return result; 602 for (int i = 0; i < children.size; i++) { 603 Element child = children.get(i); 604 if (child.name.equals(name)) result.add(child); 605 } 606 return result; 607 } 608 609 /** @param name the name of the children 610 * @return the children with the given name or an empty {@link Array} */ 611 public Array<Element> getChildrenByNameRecursively (String name) { 612 Array<Element> result = new Array<Element>(); 613 getChildrenByNameRecursively(name, result); 614 return result; 615 } 616 617 private void getChildrenByNameRecursively (String name, Array<Element> result) { 618 if (children == null) return; 619 for (int i = 0; i < children.size; i++) { 620 Element child = children.get(i); 621 if (child.name.equals(name)) result.add(child); 622 child.getChildrenByNameRecursively(name, result); 623 } 624 } 625 626 /** @throws GdxRuntimeException if the attribute was not found. */ 627 public float getFloatAttribute (String name) { 628 return Float.parseFloat(getAttribute(name)); 629 } 630 631 public float getFloatAttribute (String name, float defaultValue) { 632 String value = getAttribute(name, null); 633 if (value == null) return defaultValue; 634 return Float.parseFloat(value); 635 } 636 637 /** @throws GdxRuntimeException if the attribute was not found. */ 638 public int getIntAttribute (String name) { 639 return Integer.parseInt(getAttribute(name)); 640 } 641 642 public int getIntAttribute (String name, int defaultValue) { 643 String value = getAttribute(name, null); 644 if (value == null) return defaultValue; 645 return Integer.parseInt(value); 646 } 647 648 /** @throws GdxRuntimeException if the attribute was not found. */ 649 public boolean getBooleanAttribute (String name) { 650 return Boolean.parseBoolean(getAttribute(name)); 651 } 652 653 public boolean getBooleanAttribute (String name, boolean defaultValue) { 654 String value = getAttribute(name, null); 655 if (value == null) return defaultValue; 656 return Boolean.parseBoolean(value); 657 } 658 659 /** Returns the attribute value with the specified name, or if no attribute is found, the text of a child with the name. 660 * @throws GdxRuntimeException if no attribute or child was not found. */ 661 public String get (String name) { 662 String value = get(name, null); 663 if (value == null) throw new GdxRuntimeException("Element " + this.name + " doesn't have attribute or child: " + name); 664 return value; 665 } 666 667 /** Returns the attribute value with the specified name, or if no attribute is found, the text of a child with the name. 668 * @throws GdxRuntimeException if no attribute or child was not found. */ 669 public String get (String name, String defaultValue) { 670 if (attributes != null) { 671 String value = attributes.get(name); 672 if (value != null) return value; 673 } 674 Element child = getChildByName(name); 675 if (child == null) return defaultValue; 676 String value = child.getText(); 677 if (value == null) return defaultValue; 678 return value; 679 } 680 681 /** Returns the attribute value with the specified name, or if no attribute is found, the text of a child with the name. 682 * @throws GdxRuntimeException if no attribute or child was not found. */ 683 public int getInt (String name) { 684 String value = get(name, null); 685 if (value == null) throw new GdxRuntimeException("Element " + this.name + " doesn't have attribute or child: " + name); 686 return Integer.parseInt(value); 687 } 688 689 /** Returns the attribute value with the specified name, or if no attribute is found, the text of a child with the name. 690 * @throws GdxRuntimeException if no attribute or child was not found. */ 691 public int getInt (String name, int defaultValue) { 692 String value = get(name, null); 693 if (value == null) return defaultValue; 694 return Integer.parseInt(value); 695 } 696 697 /** Returns the attribute value with the specified name, or if no attribute is found, the text of a child with the name. 698 * @throws GdxRuntimeException if no attribute or child was not found. */ 699 public float getFloat (String name) { 700 String value = get(name, null); 701 if (value == null) throw new GdxRuntimeException("Element " + this.name + " doesn't have attribute or child: " + name); 702 return Float.parseFloat(value); 703 } 704 705 /** Returns the attribute value with the specified name, or if no attribute is found, the text of a child with the name. 706 * @throws GdxRuntimeException if no attribute or child was not found. */ 707 public float getFloat (String name, float defaultValue) { 708 String value = get(name, null); 709 if (value == null) return defaultValue; 710 return Float.parseFloat(value); 711 } 712 713 /** Returns the attribute value with the specified name, or if no attribute is found, the text of a child with the name. 714 * @throws GdxRuntimeException if no attribute or child was not found. */ 715 public boolean getBoolean (String name) { 716 String value = get(name, null); 717 if (value == null) throw new GdxRuntimeException("Element " + this.name + " doesn't have attribute or child: " + name); 718 return Boolean.parseBoolean(value); 719 } 720 721 /** Returns the attribute value with the specified name, or if no attribute is found, the text of a child with the name. 722 * @throws GdxRuntimeException if no attribute or child was not found. */ 723 public boolean getBoolean (String name, boolean defaultValue) { 724 String value = get(name, null); 725 if (value == null) return defaultValue; 726 return Boolean.parseBoolean(value); 727 } 728 } 729 } 730