Xml.hx 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349
  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. @:native("_Xml.RealXmlType")
  26. extern enum XmlType {
  27. }
  28. private enum RealXmlType {
  29. Element;
  30. PCData;
  31. CData;
  32. Comment;
  33. DocType;
  34. Prolog;
  35. Document;
  36. }
  37. @:core_api class Xml {
  38. public static var Element(default,null) : XmlType;
  39. public static var PCData(default,null) : XmlType;
  40. public static var CData(default,null) : XmlType;
  41. public static var Comment(default,null) : XmlType;
  42. public static var DocType(default,null) : XmlType;
  43. public static var Prolog(default,null) : XmlType;
  44. public static var Document(default,null) : XmlType;
  45. public var nodeType(default,null) : XmlType;
  46. public var nodeName(get_nodeName,set_nodeName) : String;
  47. public var nodeValue(get_nodeValue,set_nodeValue) : String;
  48. public var parent(getParent,null) : Xml;
  49. var _nodeName : String;
  50. var _nodeValue : String;
  51. var _attributes : Hash<String>;
  52. var _children : Array<Xml>;
  53. var _parent : Xml;
  54. public static function parse( str : String ) : Xml {
  55. return haxe.xml.Parser.parse(str);
  56. }
  57. private function new() : Void {
  58. }
  59. public static function createElement( name : String ) : Xml {
  60. var r = new Xml();
  61. r.nodeType = Xml.Element;
  62. r._children = new Array();
  63. r._attributes = new Hash();
  64. r.set_nodeName( name );
  65. return r;
  66. }
  67. public static function createPCData( data : String ) : Xml {
  68. var r = new Xml();
  69. r.nodeType = Xml.PCData;
  70. r.set_nodeValue( data );
  71. return r;
  72. }
  73. public static function createCData( data : String ) : Xml {
  74. var r = new Xml();
  75. r.nodeType = Xml.CData;
  76. r.set_nodeValue( data );
  77. return r;
  78. }
  79. public static function createComment( data : String ) : Xml {
  80. var r = new Xml();
  81. r.nodeType = Xml.Comment;
  82. r.set_nodeValue( data );
  83. return r;
  84. }
  85. public static function createDocType( data : String ) : Xml {
  86. var r = new Xml();
  87. r.nodeType = Xml.DocType;
  88. r.set_nodeValue( data );
  89. return r;
  90. }
  91. public static function createProlog( data : String ) : Xml {
  92. var r = new Xml();
  93. r.nodeType = Xml.Prolog;
  94. r.set_nodeValue( data );
  95. return r;
  96. }
  97. public static function createDocument() : Xml {
  98. var r = new Xml();
  99. r.nodeType = Xml.Document;
  100. r._children = new Array();
  101. return r;
  102. }
  103. private function get_nodeName() : String {
  104. if( nodeType != Xml.Element )
  105. throw "bad nodeType";
  106. return _nodeName;
  107. }
  108. private function set_nodeName( n : String ) : String {
  109. if( nodeType != Xml.Element )
  110. throw "bad nodeType";
  111. return _nodeName = n;
  112. }
  113. private function get_nodeValue() : String {
  114. if( nodeType == Xml.Element || nodeType == Xml.Document )
  115. throw "bad nodeType";
  116. return _nodeValue;
  117. }
  118. private function set_nodeValue( v : String ) : String {
  119. if( nodeType == Xml.Element || nodeType == Xml.Document )
  120. throw "bad nodeType";
  121. return _nodeValue = v;
  122. }
  123. private function getParent() : Xml {
  124. return _parent;
  125. }
  126. public function get( att : String ) : String {
  127. if( nodeType != Xml.Element )
  128. throw "bad nodeType";
  129. return _attributes.get( att );
  130. }
  131. public function set( att : String, value : String ) : Void {
  132. if( nodeType != Xml.Element )
  133. throw "bad nodeType";
  134. _attributes.set( att, value );
  135. }
  136. public function remove( att : String ) : Void{
  137. if( nodeType != Xml.Element )
  138. throw "bad nodeType";
  139. _attributes.remove( att );
  140. }
  141. public function exists( att : String ) : Bool {
  142. if( nodeType != Xml.Element )
  143. throw "bad nodeType";
  144. return _attributes.exists( att );
  145. }
  146. public function attributes() : Iterator<String> {
  147. if( nodeType != Xml.Element )
  148. throw "bad nodeType";
  149. return _attributes.keys();
  150. }
  151. public function iterator() : Iterator<Xml> {
  152. if ( _children == null ) throw "bad nodetype";
  153. var cur = 0;
  154. var x = this._children;
  155. return {
  156. hasNext : function(){
  157. return cur < x.length;
  158. },
  159. next : function(){
  160. return x[cur++];
  161. }
  162. }
  163. }
  164. public function elements() : Iterator<Xml> {
  165. if ( _children == null ) throw "bad nodetype";
  166. var cur = 0;
  167. var x = _children;
  168. return untyped {
  169. hasNext : function() {
  170. var k = cur;
  171. var l = x.length;
  172. while( k < l ) {
  173. if( x[k].nodeType == Xml.Element )
  174. break;
  175. k += 1;
  176. }
  177. cur = k;
  178. return k < l;
  179. },
  180. next : function() {
  181. var k = cur;
  182. var l = x.length;
  183. while( k < l ) {
  184. var n = x[k];
  185. k += 1;
  186. if( n.nodeType == Xml.Element ) {
  187. cur = k;
  188. return n;
  189. }
  190. }
  191. return null;
  192. }
  193. }
  194. }
  195. public function elementsNamed( name : String ) : Iterator<Xml> {
  196. if ( _children == null ) throw "bad nodetype";
  197. var x = _children;
  198. var cur = 0;
  199. return untyped {
  200. cur: 0,
  201. x: this._children,
  202. hasNext : function() {
  203. var k = cur;
  204. var l = x.length;
  205. while( k < l ) {
  206. var n = x[k];
  207. if( n.nodeType == Xml.Element && n._nodeName == name )
  208. break;
  209. k++;
  210. }
  211. cur = k;
  212. return k < l;
  213. },
  214. next : function() {
  215. var k = cur;
  216. var l = x.length;
  217. while( k < l ) {
  218. var n = x[k];
  219. k++;
  220. if( n.nodeType == Xml.Element && n._nodeName == name ) {
  221. cur = k;
  222. return n;
  223. }
  224. }
  225. return null;
  226. }
  227. }
  228. }
  229. public function firstChild() : Xml {
  230. if( _children == null ) throw "bad nodetype";
  231. return _children[0];
  232. }
  233. public function firstElement() : Xml {
  234. if( _children == null ) throw "bad nodetype";
  235. var cur = 0;
  236. var l = _children.length;
  237. while( cur < l ) {
  238. var n = _children[cur];
  239. if( n.nodeType == Xml.Element )
  240. return n;
  241. cur++;
  242. }
  243. return null;
  244. }
  245. public function addChild( x : Xml ) : Void {
  246. if( _children == null ) throw "bad nodetype";
  247. if( x._parent != null ) x._parent._children.remove(x);
  248. x._parent = this;
  249. _children.push( x );
  250. }
  251. public function removeChild( x : Xml ) : Bool {
  252. if( _children == null ) throw "bad nodetype";
  253. var b = _children.remove( x );
  254. if( b )
  255. x._parent = null;
  256. return b;
  257. }
  258. public function insertChild( x : Xml, pos : Int ) : Void {
  259. if( _children == null ) throw "bad nodetype";
  260. if( x._parent != null ) x._parent._children.remove(x);
  261. x._parent = this;
  262. _children.insert( pos, x );
  263. }
  264. public function toString() : String {
  265. if( nodeType == Xml.PCData )
  266. return _nodeValue;
  267. if( nodeType == Xml.CData )
  268. return "<![CDATA["+_nodeValue+"]]>";
  269. if( nodeType == Xml.Comment )
  270. return "<!--"+_nodeValue+"-->";
  271. if( nodeType == Xml.DocType )
  272. return "<!DOCTYPE "+_nodeValue+">";
  273. if( nodeType == Xml.Prolog )
  274. return "<?"+_nodeValue+"?>";
  275. var s = new StringBuf();
  276. if( nodeType == Xml.Element ) {
  277. s.add("<");
  278. s.add(_nodeName);
  279. for( k in _attributes.keys() ){
  280. s.add(" ");
  281. s.add(k);
  282. s.add("=\"");
  283. s.add(_attributes.get(k));
  284. s.add("\"");
  285. }
  286. if( _children.length == 0 ) {
  287. s.add("/>");
  288. return s.toString();
  289. }
  290. s.add(">");
  291. }
  292. for( x in iterator() )
  293. s.add(x.toString());
  294. if( nodeType == Xml.Element ) {
  295. s.add("</");
  296. s.add(_nodeName);
  297. s.add(">");
  298. }
  299. return s.toString();
  300. }
  301. static function __init__() : Void untyped {
  302. Xml.Element = cast RealXmlType.Element;
  303. Xml.PCData = cast RealXmlType.PCData;
  304. Xml.CData = cast RealXmlType.CData;
  305. Xml.Comment = cast RealXmlType.Comment;
  306. Xml.DocType = cast RealXmlType.DocType;
  307. Xml.Prolog = cast RealXmlType.Prolog;
  308. Xml.Document = cast RealXmlType.Document;
  309. }
  310. }