haXe Forum > E4X a replacement?
-
Oleg Sivokon Jan 14 at 21:46
Hi.
I've read a lot of posts on the mailing list and here in the forum regarding the subject and I came to understand that event though haxe.xml.Fast is nice and would probably be fast (as it says :) ) but, it's not as easy to use on a day to day basis as E4X.
I know that some people would rather see XPath implemented in HaXe, or have HaXe support E4X "natively" for the flash9 platform, so, I would imagine some of you may be interested in a sort of alternative solution.I don't claim it to be fast (well, I'm barely familiar with the language, so, I would gladly accept any optimization hints). And it uses high-level API, that is Xml class (so, again, I would be interested to know whether and how would I be able to make a switch for flash9 platform and probably optimize it).
However, this class came as a necessity of porting an existing AS3 project with extensive use of E4X, and I really didn't want to compile it in stages, like generating externs and then using reflection / load xml parsing code externally etc.So, you're welcome to take a look, and, I would appreciate your feedback:
http://code.google.com/p/e4xu/source/browse/trunk/haxe/src/org/wvxvws/xml/W.hxFew examples that I put together for some quick testing:
/** * ... * @author wvxvw */ package org.wvxvws; import flash.Lib; import flash.display.Sprite; import org.wvxvws.xml.W; class TestW extends Sprite { private var _xml:Xml; public function new() { super(); this._xml = Xml.parse(" <a> <b/> <b/> <b> <c foo=\"bar0\"> <d abcd=\"123\" qwerty=\"shouldn't catch\"/> </c> <c foo=\"bar1\"/> <c foo=\"bar2\"> <d abcd=\"456\" qwerty=\"678\"/> </c> <c foo=\"bar3\"/> </b> <b/> </a>"); // AS3 analogue: this._xml..*.(valueOf().@*.(toXMlString() == "bar2").length()).*.@qwerty; var a:Array<Hash<String>> = cast W.alk(this._xml).d().a(this.filter).c().a(this.filter2).z(); trace(a); // TestW.hx 36: [{qwerty=>678}] } private inline function filter(attName:String, attValue:String, node:Xml):Bool { return attValue == "bar2"; } private inline function filter2(attName:String, attValue:String, node:Xml):Bool { return attName == "qwerty"; } public static function main() { Lib.current.addChild(new TestW()); } }
this._removeWhite = ~/^[\t\s\r\n]*([^\t\s\r\n]+)*[\t\s\r\n]*$/g; W.alk(this._xml).d().t(this.filterTexts); .... private function filterTexts(text:String, node:Xml):Bool { node.nodeValue = this._removeWhite.replace(text, "$1"); return true; }
Additionally, I've started to work on XML printer (just something to get my XML printed nicely)
http://code.google.com/p/e4xu/source/browse/trunk/haxe/src/org/wvxvws/xml/X.hx
It's a work in the process, however, the functionality I needed from it is already present.I would think of writing XPath implementation, I've even started doing something like that a while back in AS3, however, in the context of AS3 the idea of XPath isn't viable, unless implemented using native code. Maybe E4X isn't as fast as it might've been, but, (sorry, no offense, whoever likes XPath!) I've spent many working hours, well, months if not years using all sorts of XML parsing libraries ranging from Java SAX parsers and Linq to XSLT and PHP / JS XPath, and, IMO E4X is just better...
OK, that's enough of me talking :) I would greatly appreciate your input! Thanks.
-
I don't know if there is more overhead with this approach which looks like it uses loops etc or loading in missing opto codes as an as3 movie ie:
package { import flash.display.MovieClip; [ SWF( backgroundColor = '0xFFFFFF', frameRate = '1', width = '1', height = '1' ) ] public class E4xHelper extends MovieClip { public function flashBrackets( data_: * , func_:Function ):XMLList{ return data_.( func_( valueOf() ) ); } } }
used along the lines of_e4XHelper = e.data; _flashBrackets = cast( _e4XHelper, E4xHelper ).flashBrackets; var xmllist: XMLList = xml.locations.child('*'); var e4xfilter = function( data_: XML ):Bool{ return data_.attribute('y').toString() == '320' || data_.attribute('x').toString() == '200'; } xmllist = _flashBrackets( xmllist, e4xfilter );
But I have found in a large project that I can get by without the missing opto codes.. well I did not end up using _flashBrackets, for instance you can do a lot without eg... xmllist exampleThe other alternative is to look at the code used in Away3Dlite for haXe, I would be interested if you have an opinion on which of the 3 approaches is better, maybe it is possible to write the opto codes with the format class rather than my hack.
It is certainly an important area as I like to have similar workflows for haXe and AS3, as different clients may specify differently and e4X is easier to use than other xml approaches for me, none of the approaches seem as nice as how it works in AS3.
-
Oleg Sivokon Jan 17 at 10:33
Hi Justin.
Yes, I knew abut Awat3D E4X class, but, things about it that trouble me are:
- it's platform dependent (apparently it uses XMLList / XML AS3 classes).
- It simply wraps around XMLList / XML methods, so, it will be calling them at runtime, which means that no special E4X bytecodes will be used.
Additionally, there are couple of annoying bugs related to XML in AS3, which this code doesn't address (most important is that you may occasionally add the same node by reference more then once, in which case you won't simply find your way out, and it's kind of an error that is hard to find...)Last thing about it - you have to use it like this:
var foo = E4X.doSomething(); foo = E4X.doSomethingElse(foo, bunch of other stuff);
Which sort of defeats the purpose of E4X (it's so good because it's short!).
So, well, performance-wise and usability-wise it may be even faster just to write the AS3 code, compile it and embed / load at runtime.My code is an attempt to not make it platform-independent and just shorter. I do have concerns related to it's productivity since I don't really know what kind of loops are best in HaXe, what underlying structures it uses on other platforms and stuff like that - so, I would be interested to hear:
Is there any difference if I do:
var xml:Xml; var iterator = xmlDocument.iterator(); while (iterator.hasNext()) { xml = iterator.next(); xml.callSomeMethod(); }
orfor (xml in xmlDocument.iterator()) xml.callSomeMethod();
Or, is it worth having a pool of arrays to hold temporary collections of nodes, or is it not worth the play? Does HaXe deal with memory allocation to structures like Array, or is that handled by the platform code? Is object instantiation in any way different in HaXe then in AS3? (AS3 construction is the slowest kind of function because it is never "JITed" - i.e. it's evaluated anew each time you call it).
Which Xml methods will be better to use, elementsNamed() or elements() and filter them on your own?
+ There are bunch more things that I don't know... like, for instance, Xml.Prolog - is this equivalent to any processing instruction, or only prolog (i.e. <?xml ?>) Sorry, was kind of lazy to check that out myself :)Anyways, if my solution looks bad, then I would be interested to know why - for me that's the way to learn, when I try and make something I know considerably good in another language and see what the old-time programmers have to say about my effort. Could be that my code is very-very bad! :D But, if I knew why it is bad, than I'd improve.
-
Oleg Sivokon Jan 17 at 10:38
Oh, another thing to ask regarding your example code:
I see even some oldtimers using anonymous functions even when targeting flash / flash9 platform... Does HaXe do any improvement to them? Because those are a big "no-no" in AS3 both regarding garbage collection and performance (they are actually created each time the function that declared them runs)... -
Oleg Sivokon Jan 17 at 10:47
Oh, sorry, just another unrelated thing: according to SWF format, the resulting SWF should never be smaller then 20x20 pixels :) I think that MXMLC would validate the SWF tag and change that from 1 pixel to 20 :) One never knows for sure... but that's what it has to do :)
-
Which iterator type is best?
Should we be looking at YAML parsing rather than XML? -
Oleg Sivokon Jan 17 at 19:20
Well, if speaking of data serialization in general, I'd stick to Protobuf :) I also think that YAML is a good thing though. However, XML beats everyone else on popularity, and usually every platform would have some native implementation which would cover most of demands.
Regarding the article - thanks, I think you've given me this link before. But, my question was rather syntax-related. Meaning: I don't know if having a local variable and iterating in "Java style" like
var a; while (a = i.moveNext())
or usingfor (a in iterator())
is the same or not.
.
Regarding what the article says about SugarList and FastList - well, I think I'm just afraid of making dependencies to things I don't know yet good enough. I would need to do some large scale testing to see if it will be better using FastList...
Thanks anyway!