Xml.hx 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320
  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. if( nodeType != Xml.Element && nodeType != Xml.Document )
  105. throw "bad nodeType";
  106. return convert(this.__x[untyped "firstChild"]);
  107. }
  108. public function firstElement() : Xml {
  109. if( nodeType != Xml.Element && nodeType != Xml.Document )
  110. throw "bad nodeType";
  111. var e : Dynamic = __x[untyped "firstChild"];
  112. while( e != null && e[untyped "nodeType"] != 1 )
  113. e = e[untyped "nextSibling"];
  114. return convert(e);
  115. }
  116. private function setNodeName( n : String ) : String {
  117. if( nodeType != Xml.Element )
  118. throw "bad nodeType";
  119. return __x[untyped "nodeName"] = n;
  120. }
  121. private function setNodeValue( v : String ) : String {
  122. if( nodeType == Xml.Element || nodeType == Xml.Document )
  123. throw "bad nodeType";
  124. return __x[untyped "nodeValue"] = v;
  125. }
  126. private function getNodeName() : String {
  127. if( nodeType != Xml.Element )
  128. throw "bad nodeType";
  129. return __x[untyped "nodeName"];
  130. }
  131. private function getNodeValue() : String {
  132. if( nodeType == Xml.Element || nodeType == Xml.Document )
  133. throw "bad nodeType";
  134. return __x[untyped "nodeValue"];
  135. }
  136. private function getParent() : Xml {
  137. return convert(__x[untyped "parentNode"]);
  138. }
  139. public function iterator() : Iterator<Xml> {
  140. if( nodeType != Xml.Document && nodeType != Xml.Element )
  141. throw "bad nodeType";
  142. return untyped {
  143. cur: this.__x[untyped "firstChild"],
  144. hasNext : function(){
  145. return __this__.cur != null;
  146. },
  147. next : function(){
  148. var r = convert(__this__.cur);
  149. __this__.cur = __this__.cur["nextSibling"];
  150. return r;
  151. }
  152. }
  153. }
  154. public function elements() : Iterator<Xml> {
  155. if( nodeType != Xml.Document && nodeType != Xml.Element )
  156. throw "bad nodeType";
  157. return untyped {
  158. cur: this.__x[untyped "firstChild"],
  159. hasNext : function() {
  160. var r = __this__.cur;
  161. while( r != null && r["nodeType"] != 1 )
  162. r = r["nextSibling"];
  163. __this__.cur = r;
  164. return r != null;
  165. },
  166. next : function(){
  167. var r = __this__.cur;
  168. while( r != null && r["nodeType"] != 1 )
  169. r = r["nextSibling"];
  170. if( r == null ) {
  171. __this__.cur = null;
  172. return null;
  173. }
  174. __this__.cur = r["nextSibling"];
  175. return convert(r);
  176. }
  177. }
  178. }
  179. public function elementsNamed( name : String ) : Iterator<Xml> {
  180. if( nodeType != Xml.Document && nodeType != Xml.Element )
  181. throw "bad nodeType";
  182. return untyped {
  183. cur: this.__x[untyped "firstChild"],
  184. hasNext : function() {
  185. var r = __this__.cur;
  186. while( r != null && (r["nodeType"] != 1 || r["nodeName"] != name) )
  187. r = r["nextSibling"];
  188. __this__.cur = r;
  189. return r != null;
  190. },
  191. next : function(){
  192. var r = __this__.cur;
  193. while( r != null && (r["nodeType"] != 1 || r["nodeName"] != name) )
  194. r = r["nextSibling"];
  195. if( r == null ) {
  196. __this__.cur = null;
  197. return null;
  198. }
  199. __this__.cur = r["nextSibling"];
  200. return convert(r);
  201. }
  202. }
  203. }
  204. public function get( att : String ) : String {
  205. if( nodeType != Xml.Element )
  206. throw "bad nodeType";
  207. return Reflect.field(__x[untyped "attributes"],att);
  208. }
  209. public function set( att : String, value : String ) : Void {
  210. if( nodeType != Xml.Element )
  211. throw "bad nodeType";
  212. return Reflect.setField(__x[untyped "attributes"],att,value);
  213. }
  214. public function exists( att : String ) : Bool {
  215. if( nodeType != Xml.Element )
  216. throw "bad nodeType";
  217. return Reflect.hasField(__x[untyped "attributes"],att);
  218. }
  219. public function remove( att : String ) : Void {
  220. if( nodeType != Xml.Element )
  221. throw "bad nodeType";
  222. Reflect.deleteField(__x[untyped "attributes"],att);
  223. }
  224. public function attributes() : Iterator<String> {
  225. if( nodeType != Xml.Element )
  226. throw "bad nodeType";
  227. return untyped __keys__(__x["attributes"])["iterator"]();
  228. }
  229. public function addChild( x : Xml ) : Void {
  230. if( nodeType != Xml.Document && nodeType != Xml.Element )
  231. throw "bad nodeType";
  232. untyped __x[untyped "appendChild"](x.__x);
  233. }
  234. public function removeChild( x : Xml ) : Bool {
  235. if( nodeType != Xml.Document && nodeType != Xml.Element )
  236. throw "bad nodeType";
  237. untyped if( x.__x["parentNode"] != __x )
  238. return false;
  239. untyped x.__x["removeNode"]();
  240. return true;
  241. }
  242. public function insertChild( x : Xml, pos : Int ) : Void {
  243. if( nodeType != Xml.Document && nodeType != Xml.Element )
  244. throw "bad nodeType";
  245. var c : Array<Dynamic> = __x[untyped "childNodes"];
  246. if( pos <= c.length )
  247. __x[untyped "insertBefore"](untyped x.__x,c[pos]);
  248. }
  249. public function toString() : String {
  250. if( nodeType == Xml.Document ){
  251. var s = "";
  252. for( c in iterator() )
  253. s += c.toString();
  254. return s;
  255. }
  256. // only works for toplevel elements
  257. if( nodeType == Xml.CData )
  258. return "<![CDATA["+__x[untyped "nodeValue"]+"]]>";
  259. if( nodeType == Xml.Prolog )
  260. return "<?"+__x[untyped "nodeValue"]+"?>";
  261. if( nodeType == Xml.DocType )
  262. return "<!DOCTYPE "+__x[untyped "nodeValue"]+">";
  263. var s : String = __x.toString();
  264. return s.split(" />").join("/>");
  265. }
  266. static function __init__() : Void untyped {
  267. Xml.Element = "element";
  268. Xml.PCData = "pcdata";
  269. Xml.CData = "cdata";
  270. Xml.Comment = "comment";
  271. Xml.DocType = "doctype";
  272. Xml.Prolog = "prolog";
  273. Xml.Document = "document";
  274. #if swf_mark
  275. flash.Lib.current["Xml"] = Xml;
  276. #end
  277. }
  278. }