Xml.hx 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316
  1. /*
  2. * Copyright (c) 2005, The haXe Project Contributors
  3. * All rights reserved.
  4. * Redistribution and use in source and binary forms, with or without
  5. * modification, are permitted provided that the following conditions are met:
  6. *
  7. * - Redistributions of source code must retain the above copyright
  8. * notice, this list of conditions and the following disclaimer.
  9. * - Redistributions in binary form must reproduce the above copyright
  10. * notice, this list of conditions and the following disclaimer in the
  11. * documentation and/or other materials provided with the distribution.
  12. *
  13. * THIS SOFTWARE IS PROVIDED BY THE HAXE PROJECT CONTRIBUTORS "AS IS" AND ANY
  14. * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  15. * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  16. * DISCLAIMED. IN NO EVENT SHALL THE HAXE PROJECT CONTRIBUTORS BE LIABLE FOR
  17. * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  18. * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  19. * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  20. * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  21. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  22. * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
  23. * DAMAGE.
  24. */
  25. enum XmlType {
  26. }
  27. @:core_api class Xml {
  28. public static var Element(default,null) : XmlType;
  29. public static var PCData(default,null) : XmlType;
  30. public static var CData(default,null) : XmlType;
  31. public static var Comment(default,null) : XmlType;
  32. public static var DocType(default,null) : XmlType;
  33. public static var Prolog(default,null) : XmlType;
  34. public static var Document(default,null) : XmlType;
  35. public var nodeName(getNodeName,setNodeName) : String;
  36. public var nodeValue(getNodeValue,setNodeValue) : String;
  37. public var parent(getParent,null) : Xml;
  38. public var nodeType(default,null) : XmlType;
  39. private var __x : Dynamic;
  40. private static function convert( o : Dynamic ) : Xml {
  41. if( o == null ) return null;
  42. if( o.__w != null ) return o.__w;
  43. var r = new Xml();
  44. r.__x = o;
  45. o.__w = r;
  46. r.nodeType = switch( untyped o["nodeType"] ) {
  47. case 1:
  48. Xml.Element;
  49. case 3:
  50. Xml.PCData;
  51. default:
  52. throw "unknow nodeType: "+untyped o["nodeType"];
  53. }
  54. return untyped r;
  55. }
  56. public static function parse( str : String ) : Xml untyped {
  57. var x = __new__(_global["XML"]);
  58. x["parseXML"](str);
  59. if( x["status"] != 0 )
  60. throw ("Xml parse error #"+x["status"]);
  61. var r = convert(x);
  62. r.nodeType = Xml.Document;
  63. return r;
  64. }
  65. public static function createDocument() : Xml {
  66. var o = untyped __new__(_global["XML"])["createElement"]( "#document" );
  67. var r = convert(o);
  68. r.nodeType = Xml.Document;
  69. return r;
  70. }
  71. public static function createCData( data : String ) : Xml {
  72. var o = untyped __new__(_global["XML"])["createTextNode"]( data );
  73. var x = convert(o);
  74. x.nodeType = Xml.CData;
  75. return x;
  76. }
  77. public static function createPCData( data : String ) : Xml {
  78. var o = untyped __new__(_global["XML"])["createTextNode"]( data );
  79. return convert(o);
  80. }
  81. public static function createElement( name : String ) : Xml {
  82. var o = untyped __new__(_global["XML"])["createElement"]( name );
  83. return convert(o);
  84. }
  85. public static function createComment( data : String ) : Xml {
  86. throw "not implemented";
  87. return null;
  88. }
  89. public static function createDocType( data : String ) : Xml {
  90. var x = createPCData("");
  91. x.nodeType = Xml.DocType;
  92. x.nodeValue = data;
  93. return x;
  94. }
  95. public static function createProlog( data : String ) : Xml {
  96. var x = createPCData("");
  97. x.nodeType = Xml.Prolog;
  98. x.nodeValue = data;
  99. return x;
  100. }
  101. private function new() : Void {
  102. }
  103. public function firstChild() : Xml {
  104. return convert(this.__x[untyped "firstChild"]);
  105. }
  106. public function firstElement() : Xml {
  107. var e : Dynamic = __x[untyped "firstChild"];
  108. while( e != null && e[untyped "nodeType"] != 1 )
  109. e = e[untyped "nextSibling"];
  110. return convert(e);
  111. }
  112. private function setNodeName( n : String ) : String {
  113. if( nodeType != Xml.Element )
  114. throw "bad nodeType";
  115. return __x[untyped "nodeName"] = n;
  116. }
  117. private function setNodeValue( v : String ) : String {
  118. if( nodeType == Xml.Element || nodeType == Xml.Document )
  119. throw "bad nodeType";
  120. return __x[untyped "nodeValue"] = v;
  121. }
  122. private function getNodeName() : String {
  123. if( nodeType != Xml.Element )
  124. throw "bad nodeType";
  125. return __x[untyped "nodeName"];
  126. }
  127. private function getNodeValue() : String {
  128. if( nodeType == Xml.Element || nodeType == Xml.Document )
  129. throw "bad nodeType";
  130. return __x[untyped "nodeValue"];
  131. }
  132. private function getParent() : Xml {
  133. return convert(__x[untyped "parentNode"]);
  134. }
  135. public function iterator() : Iterator<Xml> {
  136. if( nodeType != Xml.Document && nodeType != Xml.Element )
  137. throw "bad nodeType";
  138. return untyped {
  139. cur: this.__x[untyped "firstChild"],
  140. hasNext : function(){
  141. return __this__.cur != null;
  142. },
  143. next : function(){
  144. var r = convert(__this__.cur);
  145. __this__.cur = __this__.cur["nextSibling"];
  146. return r;
  147. }
  148. }
  149. }
  150. public function elements() : Iterator<Xml> {
  151. if( nodeType != Xml.Document && nodeType != Xml.Element )
  152. throw "bad nodeType";
  153. return untyped {
  154. cur: this.__x[untyped "firstChild"],
  155. hasNext : function() {
  156. var r = __this__.cur;
  157. while( r != null && r["nodeType"] != 1 )
  158. r = r["nextSibling"];
  159. __this__.cur = r;
  160. return r != null;
  161. },
  162. next : function(){
  163. var r = __this__.cur;
  164. while( r != null && r["nodeType"] != 1 )
  165. r = r["nextSibling"];
  166. if( r == null ) {
  167. __this__.cur = null;
  168. return null;
  169. }
  170. __this__.cur = r["nextSibling"];
  171. return convert(r);
  172. }
  173. }
  174. }
  175. public function elementsNamed( name : String ) : Iterator<Xml> {
  176. if( nodeType != Xml.Document && nodeType != Xml.Element )
  177. throw "bad nodeType";
  178. return untyped {
  179. cur: this.__x[untyped "firstChild"],
  180. hasNext : function() {
  181. var r = __this__.cur;
  182. while( r != null && (r["nodeType"] != 1 || r["nodeName"] != name) )
  183. r = r["nextSibling"];
  184. __this__.cur = r;
  185. return r != null;
  186. },
  187. next : function(){
  188. var r = __this__.cur;
  189. while( r != null && (r["nodeType"] != 1 || r["nodeName"] != name) )
  190. r = r["nextSibling"];
  191. if( r == null ) {
  192. __this__.cur = null;
  193. return null;
  194. }
  195. __this__.cur = r["nextSibling"];
  196. return convert(r);
  197. }
  198. }
  199. }
  200. public function get( att : String ) : String {
  201. if( nodeType != Xml.Element )
  202. throw "bad nodeType";
  203. return Reflect.field(__x[untyped "attributes"],att);
  204. }
  205. public function set( att : String, value : String ) : Void {
  206. if( nodeType != Xml.Element )
  207. throw "bad nodeType";
  208. return Reflect.setField(__x[untyped "attributes"],att,value);
  209. }
  210. public function exists( att : String ) : Bool {
  211. if( nodeType != Xml.Element )
  212. throw "bad nodeType";
  213. return Reflect.hasField(__x[untyped "attributes"],att);
  214. }
  215. public function remove( att : String ) : Void {
  216. if( nodeType != Xml.Element )
  217. throw "bad nodeType";
  218. Reflect.deleteField(__x[untyped "attributes"],att);
  219. }
  220. public function attributes() : Iterator<String> {
  221. if( nodeType != Xml.Element )
  222. throw "bad nodeType";
  223. return untyped __keys__(__x["attributes"])["iterator"]();
  224. }
  225. public function addChild( x : Xml ) : Void {
  226. if( nodeType != Xml.Document && nodeType != Xml.Element )
  227. throw "bad nodeType";
  228. untyped __x[untyped "appendChild"](x.__x);
  229. }
  230. public function removeChild( x : Xml ) : Bool {
  231. if( nodeType != Xml.Document && nodeType != Xml.Element )
  232. throw "bad nodeType";
  233. untyped if( x.__x["parentNode"] != __x )
  234. return false;
  235. untyped x.__x["removeNode"]();
  236. return true;
  237. }
  238. public function insertChild( x : Xml, pos : Int ) : Void {
  239. if( nodeType != Xml.Document && nodeType != Xml.Element )
  240. throw "bad nodeType";
  241. var c : Array<Dynamic> = __x[untyped "childNodes"];
  242. if( pos <= c.length )
  243. __x[untyped "insertBefore"](untyped x.__x,c[pos]);
  244. }
  245. public function toString() : String {
  246. if( nodeType == Xml.Document ){
  247. var s = "";
  248. for( c in iterator() )
  249. s += c.toString();
  250. return s;
  251. }
  252. // only works for toplevel elements
  253. if( nodeType == Xml.CData )
  254. return "<![CDATA["+__x[untyped "nodeValue"]+"]]>";
  255. if( nodeType == Xml.Prolog )
  256. return "<?"+__x[untyped "nodeValue"]+"?>";
  257. if( nodeType == Xml.DocType )
  258. return "<!DOCTYPE "+__x[untyped "nodeValue"]+">";
  259. var s : String = __x.toString();
  260. return s.split(" />").join("/>");
  261. }
  262. static function __init__() : Void untyped {
  263. Xml.Element = "element";
  264. Xml.PCData = "pcdata";
  265. Xml.CData = "cdata";
  266. Xml.Comment = "comment";
  267. Xml.DocType = "doctype";
  268. Xml.Prolog = "prolog";
  269. Xml.Document = "document";
  270. #if swf_mark
  271. flash.Lib.current["Xml"] = Xml;
  272. #end
  273. }
  274. }