Xml.hx 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316
  1. /*
  2. * Copyright (C)2005-2012 Haxe Foundation
  3. *
  4. * Permission is hereby granted, free of charge, to any person obtaining a
  5. * copy of this software and associated documentation files (the "Software"),
  6. * to deal in the Software without restriction, including without limitation
  7. * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  8. * and/or sell copies of the Software, and to permit persons to whom the
  9. * Software is furnished to do so, subject to the following conditions:
  10. *
  11. * The above copyright notice and this permission notice shall be included in
  12. * all copies or substantial portions of the Software.
  13. *
  14. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  17. * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  18. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  19. * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
  20. * DEALINGS IN THE SOFTWARE.
  21. */
  22. enum XmlType {
  23. }
  24. @:coreApi class Xml {
  25. public static var Element(default,null) : XmlType;
  26. public static var PCData(default,null) : XmlType;
  27. public static var CData(default,null) : XmlType;
  28. public static var Comment(default,null) : XmlType;
  29. public static var DocType(default,null) : XmlType;
  30. public static var Prolog(default,null) : XmlType;
  31. public static var Document(default,null) : XmlType;
  32. public var nodeName(get,set) : String;
  33. public var nodeValue(get,set) : String;
  34. public var parent(get,null) : Xml;
  35. public var nodeType(default,null) : XmlType;
  36. private var __x : Dynamic;
  37. private static function convert( o : Dynamic ) : Xml {
  38. if( o == null ) return null;
  39. if( o.__w != null ) return o.__w;
  40. var r = new Xml();
  41. r.__x = o;
  42. o.__w = r;
  43. r.nodeType = switch( untyped o["nodeType"] ) {
  44. case 1:
  45. Xml.Element;
  46. case 3:
  47. Xml.PCData;
  48. default:
  49. throw "unknow nodeType: "+untyped o["nodeType"];
  50. }
  51. return untyped r;
  52. }
  53. public static function parse( str : String ) : Xml untyped {
  54. var x = __new__(_global["XML"]);
  55. x["parseXML"](str);
  56. if( x["status"] != 0 )
  57. throw ("Xml parse error #"+x["status"]);
  58. var r = convert(x);
  59. r.nodeType = Xml.Document;
  60. return r;
  61. }
  62. public static function createDocument() : Xml {
  63. var o = untyped __new__(_global["XML"])["createElement"]( "#document" );
  64. var r = convert(o);
  65. r.nodeType = Xml.Document;
  66. return r;
  67. }
  68. public static function createCData( data : String ) : Xml {
  69. var o = untyped __new__(_global["XML"])["createTextNode"]( data );
  70. var x = convert(o);
  71. x.nodeType = Xml.CData;
  72. return x;
  73. }
  74. public static function createPCData( data : String ) : Xml {
  75. var o = untyped __new__(_global["XML"])["createTextNode"]( data );
  76. return convert(o);
  77. }
  78. public static function createElement( name : String ) : Xml {
  79. var o = untyped __new__(_global["XML"])["createElement"]( name );
  80. return convert(o);
  81. }
  82. public static function createComment( data : String ) : Xml {
  83. throw "not implemented";
  84. return null;
  85. }
  86. public static function createDocType( data : String ) : Xml {
  87. var x = createPCData("");
  88. x.nodeType = Xml.DocType;
  89. x.nodeValue = data;
  90. return x;
  91. }
  92. public static function createProlog( data : String ) : Xml {
  93. var x = createPCData("");
  94. x.nodeType = Xml.Prolog;
  95. x.nodeValue = data;
  96. return x;
  97. }
  98. private function new() : Void {
  99. }
  100. public function firstChild() : Xml {
  101. if( nodeType != Xml.Element && nodeType != Xml.Document )
  102. throw "bad nodeType";
  103. return convert(this.__x[untyped "firstChild"]);
  104. }
  105. public function firstElement() : Xml {
  106. if( nodeType != Xml.Element && nodeType != Xml.Document )
  107. throw "bad nodeType";
  108. var e : Dynamic = __x[untyped "firstChild"];
  109. while( e != null && e[untyped "nodeType"] != 1 )
  110. e = e[untyped "nextSibling"];
  111. return convert(e);
  112. }
  113. private function set_nodeName( n : String ) : String {
  114. if( nodeType != Xml.Element )
  115. throw "bad nodeType";
  116. return __x[untyped "nodeName"] = n;
  117. }
  118. private function set_nodeValue( v : String ) : String {
  119. if( nodeType == Xml.Element || nodeType == Xml.Document )
  120. throw "bad nodeType";
  121. return __x[untyped "nodeValue"] = v;
  122. }
  123. private function get_nodeName() : String {
  124. if( nodeType != Xml.Element )
  125. throw "bad nodeType";
  126. return __x[untyped "nodeName"];
  127. }
  128. private function get_nodeValue() : String {
  129. if( nodeType == Xml.Element || nodeType == Xml.Document )
  130. throw "bad nodeType";
  131. return __x[untyped "nodeValue"];
  132. }
  133. private function get_parent() : Xml {
  134. return convert(__x[untyped "parentNode"]);
  135. }
  136. public function iterator() : Iterator<Xml> {
  137. if( nodeType != Xml.Document && nodeType != Xml.Element )
  138. throw "bad nodeType";
  139. return untyped {
  140. cur: this.__x[untyped "firstChild"],
  141. hasNext : function(){
  142. return __this__.cur != null;
  143. },
  144. next : function(){
  145. var r = convert(__this__.cur);
  146. __this__.cur = __this__.cur["nextSibling"];
  147. return r;
  148. }
  149. }
  150. }
  151. public function elements() : Iterator<Xml> {
  152. if( nodeType != Xml.Document && nodeType != Xml.Element )
  153. throw "bad nodeType";
  154. return untyped {
  155. cur: this.__x[untyped "firstChild"],
  156. hasNext : function() {
  157. var r = __this__.cur;
  158. while( r != null && r["nodeType"] != 1 )
  159. r = r["nextSibling"];
  160. __this__.cur = r;
  161. return r != null;
  162. },
  163. next : function(){
  164. var r = __this__.cur;
  165. while( r != null && r["nodeType"] != 1 )
  166. r = r["nextSibling"];
  167. if( r == null ) {
  168. __this__.cur = null;
  169. return null;
  170. }
  171. __this__.cur = r["nextSibling"];
  172. return convert(r);
  173. }
  174. }
  175. }
  176. public function elementsNamed( name : String ) : Iterator<Xml> {
  177. if( nodeType != Xml.Document && nodeType != Xml.Element )
  178. throw "bad nodeType";
  179. return untyped {
  180. cur: this.__x[untyped "firstChild"],
  181. hasNext : function() {
  182. var r = __this__.cur;
  183. while( r != null && (r["nodeType"] != 1 || r["nodeName"] != name) )
  184. r = r["nextSibling"];
  185. __this__.cur = r;
  186. return r != null;
  187. },
  188. next : function(){
  189. var r = __this__.cur;
  190. while( r != null && (r["nodeType"] != 1 || r["nodeName"] != name) )
  191. r = r["nextSibling"];
  192. if( r == null ) {
  193. __this__.cur = null;
  194. return null;
  195. }
  196. __this__.cur = r["nextSibling"];
  197. return convert(r);
  198. }
  199. }
  200. }
  201. public function get( att : String ) : String {
  202. if( nodeType != Xml.Element )
  203. throw "bad nodeType";
  204. return Reflect.field(__x[untyped "attributes"],att);
  205. }
  206. public function set( att : String, value : String ) : Void {
  207. if( nodeType != Xml.Element )
  208. throw "bad nodeType";
  209. return Reflect.setField(__x[untyped "attributes"],att,value);
  210. }
  211. public function exists( att : String ) : Bool {
  212. if( nodeType != Xml.Element )
  213. throw "bad nodeType";
  214. return Reflect.hasField(__x[untyped "attributes"],att);
  215. }
  216. public function remove( att : String ) : Void {
  217. if( nodeType != Xml.Element )
  218. throw "bad nodeType";
  219. Reflect.deleteField(__x[untyped "attributes"],att);
  220. }
  221. public function attributes() : Iterator<String> {
  222. if( nodeType != Xml.Element )
  223. throw "bad nodeType";
  224. return untyped __keys__(__x["attributes"])["iterator"]();
  225. }
  226. public function addChild( x : Xml ) : Void {
  227. if( nodeType != Xml.Document && nodeType != Xml.Element )
  228. throw "bad nodeType";
  229. untyped __x[untyped "appendChild"](x.__x);
  230. }
  231. public function removeChild( x : Xml ) : Bool {
  232. if( nodeType != Xml.Document && nodeType != Xml.Element )
  233. throw "bad nodeType";
  234. untyped if( x.__x["parentNode"] != __x )
  235. return false;
  236. untyped x.__x["removeNode"]();
  237. return true;
  238. }
  239. public function insertChild( x : Xml, pos : Int ) : Void {
  240. if( nodeType != Xml.Document && nodeType != Xml.Element )
  241. throw "bad nodeType";
  242. var c : Array<Dynamic> = __x[untyped "childNodes"];
  243. if( pos <= c.length )
  244. __x[untyped "insertBefore"](untyped x.__x,c[pos]);
  245. }
  246. public function toString() : String {
  247. if( nodeType == Xml.Document ){
  248. var s = "";
  249. for( c in iterator() )
  250. s += c.toString();
  251. return s;
  252. }
  253. // only works for toplevel elements
  254. if( nodeType == Xml.CData )
  255. return "<![CDATA["+__x[untyped "nodeValue"]+"]]>";
  256. if( nodeType == Xml.Prolog )
  257. return "<?"+__x[untyped "nodeValue"]+"?>";
  258. if( nodeType == Xml.DocType )
  259. return "<!DOCTYPE "+__x[untyped "nodeValue"]+">";
  260. var s : String = __x.toString();
  261. return s.split(" />").join("/>");
  262. }
  263. static function __init__() : Void untyped {
  264. Xml.Element = "element";
  265. Xml.PCData = "pcdata";
  266. Xml.CData = "cdata";
  267. Xml.Comment = "comment";
  268. Xml.DocType = "doctype";
  269. Xml.Prolog = "prolog";
  270. Xml.Document = "document";
  271. #if swf_mark
  272. flash.Lib.current["Xml"] = Xml;
  273. #end
  274. }
  275. }