1 28 29 30 package com.caucho.quercus.lib.simplexml; 31 32 import com.caucho.quercus.env.*; 33 import com.caucho.vfs.WriteStream; 34 35 import org.w3c.dom.Document ; 36 import org.w3c.dom.Element ; 37 import org.w3c.dom.NamedNodeMap ; 38 import org.w3c.dom.Node ; 39 import org.w3c.dom.NodeList ; 40 import org.xml.sax.InputSource ; 41 42 import javax.xml.xpath.XPath ; 43 import javax.xml.xpath.XPathConstants ; 44 import javax.xml.xpath.XPathExpressionException ; 45 import javax.xml.xpath.XPathFactory ; 46 import java.io.ByteArrayInputStream ; 47 import java.io.IOException ; 48 import java.util.HashMap ; 49 import java.util.IdentityHashMap ; 50 import java.util.Iterator ; 51 import java.util.Map ; 52 import java.util.Set ; 53 54 57 58 public class SimpleXMLElement 59 { 60 private Env _env; 61 private Document _document; 62 private Element _element; 63 64 private Value _attributes; 65 66 private HashMap <StringValue, Value> _childMap; 67 68 69 75 public SimpleXMLElement(Env env, 76 Document document, 77 Element element) 78 { 79 _env = env; 80 _document = document; 81 _element = element; 82 } 83 84 88 public Value attributes() 89 { 90 NamedNodeMap attrs = _element.getAttributes(); 91 int attrLength = attrs.getLength(); 92 93 if (attrLength > 0) { 94 _attributes = new ArrayValueImpl(); 95 96 for (int j=0; j < attrLength; j++) { 97 Node attribute = attrs.item(j); 98 StringValue nodeName = new StringValueImpl(attribute.getNodeName()); 99 StringValue nodeValue = new StringValueImpl(attribute.getNodeValue()); 100 _attributes.put(nodeName, nodeValue); 101 } 102 103 } else { 104 105 _attributes = NullValue.NULL; 106 107 } 108 109 return _attributes; 110 } 111 112 115 public void fillChildMap() 116 { 117 NodeList children = _element.getChildNodes(); 118 int nodeLength = children.getLength(); 119 120 _childMap = new HashMap <StringValue, Value>(); 121 122 if (nodeLength == 0) 123 return; 124 125 if ((nodeLength == 1) && (children.item(0).getNodeType() == Node.TEXT_NODE)) { 128 String value = children.item(0).getNodeValue(); 129 130 _childMap.put(new StringValueImpl("0"), new StringValueImpl(value)); 131 } else { 132 for (int i=0; i < nodeLength; i++) { 133 Node child = children.item(i); 134 135 if (child.getNodeType() != Node.ELEMENT_NODE) 136 continue; 137 138 StringValue childTagName = new StringValueImpl(child.getNodeName()); 139 140 ArrayValue childArray = (ArrayValue) _childMap.get(childTagName); 144 if (childArray == null) { 145 childArray = new SimpleXMLElementArray(); 146 _childMap.put(childTagName, childArray); 147 } 148 149 childArray.put(_env.wrapJava(new SimpleXMLElement(_env, _document, (Element ) child))); 150 } 151 152 Set keyValues = _childMap.entrySet(); 155 int keyLength = keyValues.size(); 156 Iterator keyIterator = keyValues.iterator(); 157 for (int i=0; i < keyLength; i++) { 158 Map.Entry entry = (Map.Entry ) keyIterator.next(); 159 ArrayValue childArray = (ArrayValue) entry.getValue(); 160 161 if (childArray.getSize() == 1) { 162 Value value = childArray.get(LongValue.ZERO); 163 164 _childMap.put((StringValue) entry.getKey(), value); 165 } 166 } 167 } 168 } 169 170 175 public Value children() 176 { 177 ArrayValue childArray = new ArrayValueImpl(); 178 179 NodeList children = _element.getChildNodes(); 180 int nodeLength = children.getLength(); 181 182 for (int i = 0; i < nodeLength; i++) { 183 Node child = children.item(i); 184 185 if (child.getNodeType() != Node.ELEMENT_NODE) 186 continue; 187 188 childArray.put(_env.wrapJava(new SimpleXMLElement(_env, _document, (Element ) child))); 189 } 190 191 if (childArray.getSize() > 0) 192 return childArray; 193 else 194 return NullValue.NULL; 195 } 196 197 202 public Value __getField(String name) 203 { 204 SimpleXMLElementArray simpleArray = new SimpleXMLElementArray(); 205 206 NodeList children = _element.getChildNodes(); 207 int length = children.getLength(); 208 209 for (int i=0; i < length; i++) { 210 Node child = children.item(i); 211 212 if (child.getNodeType() != Node.ELEMENT_NODE) 213 continue; 214 215 if (name.equals(child.getNodeName())) { 218 simpleArray.put(_env.wrapJava(new SimpleXMLElement(_env, _document, (Element ) child))); 219 } 220 } 221 222 return simpleArray; 223 } 224 225 230 public Value __get(Value name) 231 { 232 NamedNodeMap attrs = _element.getAttributes(); 233 int attrLength = attrs.getLength(); 234 String attrName = name.toString(); 235 236 for (int i = 0; i < attrLength; i++) { 237 Node attr = attrs.item(i); 238 if (attrName.equals(attr.getNodeName())) 239 return new StringValueImpl(attr.getNodeValue()); 240 } 241 242 return NullValue.NULL; 243 } 244 245 251 public void __set(String name, String value) 252 { 253 _element.setAttribute(name, value); 254 255 } 256 257 260 public String toString() 261 { 262 NodeList children = _element.getChildNodes(); 264 if ((children.getLength() == 1) 265 && (children.item(0).getNodeType() == Node.TEXT_NODE)) { 266 return children.item(0).getNodeValue(); 267 } 268 269 return ""; 270 } 271 277 291 292 public Value __setField(Env env, String name, String value) 293 { 294 NodeList children = _element.getChildNodes(); 297 int length = children.getLength(); 298 299 if (length == 0) 300 return NullValue.NULL; 301 302 int indexOfFoundChild = -1; 305 for(int i = 0; i < length; i++) { 306 if (name.equals(children.item(i).getNodeName())) { 307 if (indexOfFoundChild != -1) { 308 env.warning("Cannot assign to an array of nodes (duplicate subnodes or attr detected)"); 309 return NullValue.NULL; 310 } 311 indexOfFoundChild = i; 312 } 313 } 314 315 if (indexOfFoundChild != -1) { 316 Node child = children.item(indexOfFoundChild); 317 318 while (child.hasChildNodes()) 319 child.removeChild(child.getFirstChild()); 320 321 child.appendChild(_document.createTextNode(value)); 322 } 323 324 return NullValue.NULL; 325 } 326 327 331 public Value asXML() 332 { 333 return new StringValueImpl(DOMNodeUtil.asXML(_element).toString()); 334 } 335 336 343 public Value xpath(String path) 344 throws XPathExpressionException 345 { 346 XPath xpath = XPathFactory.newInstance().newXPath(); 347 348 InputSource is = new InputSource (new ByteArrayInputStream (asXML().toString().getBytes())); 349 350 NodeList nodes = (NodeList ) xpath.evaluate(path, is, XPathConstants.NODESET); 351 352 int nodeLength = nodes.getLength(); 353 354 if (nodeLength == 0) 355 return NullValue.NULL; 356 357 Value result = new SimpleXMLElementArray(); 359 for (int i = 0; i < nodeLength; i++) { 360 result.put(_env.wrapJava(new SimpleXMLElement(_env, _document, (Element ) nodes.item(i)))); 361 } 362 363 return result; 364 } 365 366 private void printAttributes(WriteStream out, 367 int depth) 368 throws IOException 369 { 370 attributes(); 371 372 if (_attributes != NullValue.NULL) { 374 printDepth(out, 4 * (depth + 1)); 375 out.println("[@attributes] => Array"); 376 printDepth(out, 4 * (depth + 2)); 377 out.println('('); 378 379 for (Map.Entry <Value, Value> mapEntry : ((ArrayValue) _attributes).entrySet()) { 381 ArrayValue.Entry entry = (ArrayValue.Entry) mapEntry; 382 printDepth(out, 4 * (depth + 3)); 383 out.println("[" + entry.getKey().toString() + "] => " + entry.getValue().toString()); 384 } 385 out.println(); 386 printDepth(out, 4 * (depth + 2)); 387 out.println(')'); 388 } 389 } 390 391 public void printRImpl(Env env, 392 WriteStream out, 393 int depth, 394 IdentityHashMap <Value, String > valueSet) 395 throws IOException , Throwable 396 { 397 if (depth == 0) { 398 out.println("SimpleXMLElement Object"); 399 out.println('('); 400 } 401 402 fillChildMap(); 405 406 Set keyValues = _childMap.entrySet(); 407 int keyLength = keyValues.size(); 408 Iterator keyIterator = keyValues.iterator(); 409 Map.Entry entry; 410 411 if (keyIterator.hasNext()) { 412 entry = (Map.Entry ) keyIterator.next(); 413 414 if (entry.getValue() instanceof StringValue) { 415 if (depth == 0) { 416 printDepth(out, 4); 417 out.print("[0] => "); 418 } 419 420 out.println(entry.getValue().toString()); 421 } else { 422 if (depth != 0) { 423 out.println("SimpleXMLElement Object"); 424 425 printDepth(out, 4 * depth); 426 out.println('('); 427 } 428 429 printAttributes(out, depth); 430 431 keyIterator = keyValues.iterator(); 434 for (int i = 0; i < keyLength; i++) { 435 entry = (Map.Entry ) keyIterator.next(); 436 printDepth(out, 4 * (depth + 1)); 437 out.print("[" + entry.getKey() + "] => "); 438 if (entry.getValue() instanceof ArrayValue) { 439 out.println("Array"); 440 printDepth(out, 4 * (depth + 2)); 441 out.println('('); 442 for (Map.Entry <Value, Value> mapEntry : ((ArrayValue) entry.getValue()).entrySet()) { 444 printDepth(out, 4 * (depth + 3)); 445 out.print("[" + mapEntry.getKey().toString() + "] => "); 446 mapEntry.getValue().printR(env, out, depth + 4, valueSet); 447 out.println(); 448 } 449 printDepth(out, 4 * (depth + 2)); 450 out.println(')'); 451 } else 452 ((Value) entry.getValue()).printR(env, out, depth + 2, valueSet); 453 454 out.println(); 455 } 456 457 if (depth != 0) { 459 printDepth(out, 4 * depth); 460 out.println(")"); 461 } 462 } 463 } else { 464 if (depth != 0) { 465 out.println("SimpleXMLElement Object"); 466 467 printDepth(out, 4 * depth); 468 out.println('('); 469 470 printAttributes(out, depth); 471 printDepth(out, 4 * depth); 472 out.println(')'); 473 } 474 } 475 476 if (depth == 0) 477 out.println(')'); 478 } 479 480 protected void printDepth(WriteStream out, int depth) 481 throws IOException 482 { 483 for (int i = 0; i < depth; i++) 484 out.print(' '); 485 } 486 } 487 | Popular Tags |