PDA

View Full Version : Weird XML behavior: Automatic escaping and stubborn nodes



LookAtBillyFlex
September 15th, 2009, 01:57 PM
What I'm trying to do here is to build a simple XML document and then submit it to a PHP script.

I'm having 2 major problems:

1. Building the XML document. I'm not sure that I'm doing it right. If I don't first create a root node (mapXML = <xml/>; ) then it refuses to create any nodes. I would prefer to create "planet" as the root node, but if I do that instead then it just duplicates it (planet -> planet -> other child nodes....)

2. Even more annoying, it's escaping the quotation marks, no matter what I do. In the final XML document there are backslashes before the quotes.

At this point I'm not really certain at what point it's happening, whether it's in the XML parsing or whether it happens when I prepare the data for uploading. I'm submitting a large Base-64 encoded chunk, though, so URLLoaderDataFormat.VARIABLES is out



mapXML = <xml/>;
mapXML.planet.@id = "1";
mapXML.planet.map.layer.@id = "0";
mapXML.planet.map.layer.data = mapBase64;

variables.xml = mapXML.toXMLString();

request.url = "http://localhost/map_uploader.php";
request.method = URLRequestMethod.POST;
request.data = variables;

loader.dataFormat = URLLoaderDataFormat.BINARY;
loader.addEventListener(Event.COMPLETE, saveComplete);(bonus question: I decided I might want to compress the data before base-64 encoding it, since the map data is very large - 500x500 bytes. I tried deflate() with my ByteArray object. Didn't work. Said the method was undefined. Tried compress(). That worked. Why? The docs say it should be the other way around, that compress() only works in AIR. I am not compiling for AIR, and this .swf runs in the webbrowser just fine, compression and all)

wvxvw
September 15th, 2009, 02:40 PM
1. If you need to compress - use AMF, no point in trying to compress XMLs, you won't do it any way close to what AMF can offer.
2. Don't use URLLoaderDataFormat.VARIABLES until the URLVariables.decode() is fixed... sadly, this format isn't really usable. If you want to send XML, send it with default URLLoaderDataFormat - URLLoaderDataFormat.TEXT.
3. The problem with quotes seems more like PHP issue, it's in PHP installation settings whether to escape quotes or not, most hosts that offer PHP hosting will do this, so, you'll have to unescape them back on PHP side. If you have control over the PHP installation, simply find it in php.ini and comment away. I really have no idea what kind of security threat unescaped quotes may pose... but people do it anyway... just sort of weird tradition :)

4. It looks like you're trying to build your XML in an AS2 way, where the root node of XML was it's firstChild - in AS3 XML this is not true any more, so, what you should be doing ought to look more like this:

mapXML =
<planet id={"1"}>
<map>
<layer id={"0"}>
<data>{ mapBase64 }</data>
</layer>
</map>
</planet>;

request.url = "http://localhost/map_uploader.php";
request.method = URLRequestMethod.POST;
request.data = mapXML.toXMLString();

loader.dataFormat = URLLoaderDataFormat.TEXT;
loader.addEventListener(Event.COMPLETE, saveComplete);
Notice the id={"0"} thing, in this code it is redundant because you may type the value without curly braces, but I assumed you may need it later because it seems you wanted it to not be hardcoded.

LookAtBillyFlex
September 16th, 2009, 12:17 PM
1 - Thanks for the heads up about AMF. I looked it up, though, and the blog post I found said that it uses zlib for compression. Compress() does as well, so there won't be any difference in compression ratio. I think I'll stick with the current scheme, because it's less trouble. I already have XML handling so I don't need its serialization, and for decompression it's just one line of code in PHP - gzuncompress(). That's a lot less trouble than installing AMFPHP :)

I was just curious why one method worked when it shouldn't, and one didn't work when it should. Reading the docs, I think I answered my own question. compress() isn't actually available only in AIR (as I thought the little icon indicated), it's just restricted to zlib format and not deflate or gzip. Also I think I was reading the Flex 4 beta docs on accident because deflate() indeed doesn't exist before that :) (So they're adding deflate() but still not letting you choose deflate for compress()? ARGH, my head!)

2 - Thanks, I'll do that. I wasn't really sure what I was supposed to be doing there.

3 - Yeah that was a dumb question on my part. Hours of frustration later I discover that indeed I had magic_quotes_gpc turned on. I have always hated that feature. I knew about it and everything, I just forgot about it and didn't realize it was enabled on my computer (And in case you're curious the purpose of that feature is to prevent SQL injection attacks. The short version of it is that you can submit data formatted such that the quotes break out of the programmer's SQL query and let you append your own SQL code)

4 - And finally, the XML. This was the stickiest problem. I may indeed have been doing it the AS2 way. That's what I'm used to, and I'm just now trying to make the transition to AS3.

You say the root node isn't the firstChild, but how can this be? From what I learned, a well-formed XML document requires exactly one root node.

I would strongly prefer to build my XML with the dot syntax. According to the docs that syntax exists, but I'm just wondering in what way I'm doing it wrong, because I can't see why that syntax shouldn't work. You're allowed to choose whatever you want for your root node, so I don't see why it can't be planet.

I should have actually posted this version of the code


//Create the XML document
mapXML.ignoreWhitespace = false;
mapXML = <planet/>;
mapXML.planet.@id = 1;
mapXML.planet.map.layer.@id = "0";
mapXML.planet.map.layer.data = mapBase64;I expect it to modify the existing root node of planet, but instead it appends a new node. I can't see why it would be doing this. It can't be the addition of attributes to the root node, because it's valid for a root node to have attributes

For clarity, the resulting XML document looks like this:



<planet>
<planet id="1">
<map>
<layer id="0">
<data>

(and then 250KB of data and closing tags)

However, if I don't create a root node manually first then it doesn't create the XML at all.

wvxvw
September 16th, 2009, 12:55 PM
>> 1 - Thanks for the heads up about AMF. I looked it up, though, and the blog post I found said that it uses zlib for compression. Compress() does as well, so there won't be any difference in compression ratio. I think I'll stick with the current scheme, because it's less trouble. I already have XML handling so I don't need its serialization, and for decompression it's just one line of code in PHP - gzuncompress(). That's a lot less trouble than installing AMFPHP
-------------
You are mistaken, well, go back and look at AMF format again... Even if you don't compress it, it may be 2-10 times smaller then your compressed XML... not a chance it will be the same size. Besides, you really need zlib only if you're sending AS3 ByteArray to PHP and if you have compressed it...

>> mapXML.ignoreWhitespace
XML class has no instance properties, however, there are few static properties. By doing mapXML.ignoreWhitespace = true you simply create a new node with the name ignoreWhitespace

var xml:XML = <foo/>;
xml.ignoreWhitespace = true;
trace(xml.toXMLString());
/*
<foo>
<ignoreWhitespace>true</ignoreWhitespace>
</foo>
*/


Line by line:
mapXML.ignoreWhitespace = false;
^---------------------------------- Objects of XML type have no properties
ignoreWhitespace is a static property.
mapXML = <planet/>;
mapXML.planet.@id = 1;
^-------------------------------------- mapXML has no child node with the name
"planet", "planet" is the name of the root node.
mapXML.planet.map.layer.@id = "0";
^--------------------------- mapXML.planet.map.layer is an XMLList, not an
XML, assignement to the multiple items in the
XMLList is not possible.
mapXML.planet.map.layer.data = mapBase64;
^---------------------- Same as the previos one.

LookAtBillyFlex
September 17th, 2009, 03:19 AM
You are mistaken, well, go back and look at AMF format again... Even if you don't compress it, it may be 2-10 times smaller then your compressed XML... not a chance it will be the same size. Besides, you really need zlib only if you're sending AS3 ByteArray to PHP and if you have compressed it...[/code]

No, I'm not. You're confusing compression with serialization. I'm not interested in choosing AMF's object serialization format over XML.

Yes, the serialized data is smaller because of the way it's encoded. Great. It can win a format holy war then. Woo.

That's not interesting to me. I'm interested only in compressing a 250KB chunk, not the 2KB of XML that surrounds it. I'm talking about the compression, not the difference in data size that results from serialization. If AMF uses zlib (it apparently does), then there's no difference in the compression of this data.

Anyway, I figured out the xml thing. After creating the root node, mapXML refers to the root. So of COURSE mapXML.planet will be a child node called planet. Duh xD Why I didn't I figure that out earlier. Geez....

wvxvw
September 17th, 2009, 02:21 PM
>> No, I'm not. You're confusing compression with serialization. I'm not interested in choosing AMF's object serialization format over XML.

Sorry, but yes you are. I'm not confusing it because I've done that hundreds of times... AMF does not use zlib, read the specs:
http://opensource.adobe.com/wiki/download/attachments/1114283/amf3_spec_05_05_08.pdf
And my point is that if you ware using the serialization that suites your goal better you may not need to compress your data at all. The only benefit of XML is that it is human readable, but since you're pushing there the Base64 encoded text (which, btw makes it only grow in size) you totally and absolutely misuse it.

LookAtBillyFlex
September 18th, 2009, 10:33 AM
>> No, I'm not. You're confusing compression with serialization. I'm not interested in choosing AMF's object serialization format over XML.

Sorry, but yes you are. I'm not confusing it because I've done that hundreds of times... AMF does not use zlib, read the specs:
http://opensource.adobe.com/wiki/download/attachments/1114283/amf3_spec_05_05_08.pdf
And my point is that if you ware using the serialization that suites your goal better you may not need to compress your data at all. The only benefit of XML is that it is human readable, but since you're pushing there the Base64 encoded text (which, btw makes it only grow in size) you totally and absolutely misuse it.

I never disagreed that the AMF serialization format would achieve a smaller data size in this case, and in fact I reiterated that point in my previous post. What I said, in effect, is that the

difference for my particular dataset is trivial, and also that nobody cares

As I said, I don't care that AMF can win a pissing contest over who can transmit the smallest amount of data. You're essentially arguing "There's no reason for XML to exist".

As for zlib...I don't care whether it uses it or not. That was just a speculative comment: "Okay, I looked up this thing you mentioned just a second ago - which I didn't ask about and don't care about, but which you're a zealot for and insist I should use even though I don't need it and don't want it - and I found a post somewhere claiming it uses zlib. If it does indeed use zlib, then would be no substantial difference in sizes"

http://www.onflex.org/ted/2007/11/abcs-of-amf.php

He claimed it uses zlib, a comment replies that it doesn't use zlib after all. Whooptie do. On contrary, that makes AMF even less useful to me, and less relevant.

You should campaign for Adobe to remove XML support because apparently everyone should use AMF all the time, according to you.

And if it doesn't use ZLIB, then you DON'T understand what compression is. Serialization is not compression. Keep thumping your chest but you're still wrong about the difference between these words

wvxvw
September 18th, 2009, 11:14 AM
I never said that "There's no reason for XML to exist" like I never said that serialization and compression are the same, please use the forum feature for quoting if you want to quote someone... What I say is that you have chosen to do something that is fairly simple in a very complicated and inefficient way. That's it.

Believe also that you're not the first person I have to explain that s/he's using XML for the wrong purpose. Mostly people with some background in AJAX + some back-end technology for it would argue this. And that would be because it's the only way they know to do things and they are to stubborn and to self-confident to even imagine there may be alternative, and, oh, the horror! the better way to do it...

So, try to think of it like this: by creating an XML you already create a high % of redundant information that is only needed for debugging. I.e. XML is easy to read, thus, if you make mistakes in transferring the data you will easily find them. But once you're making the XML's content unreadable you loose this ability, while you retain the use of redundant technology...

Now, compression is a very processor and memory intensive procedure. AS3, even though it is quite fast comparing to other ES languages, is still very slow comparing to what the native code can do. It has some APIs for compression, but those you don't want to use... instead you want to use some library written in AS3, I assume corelib, or crypto or something like that to produce the output, and this is even more slow... And this is instead of using serialization that is accomplished by use of native API + compression that is again made by using native API... So, what you do, is more like building a jet to deliver a note to your neighbor who lives next door to you...

I really don't hope to convince you. I'm putting this here for others who may read this thread too, so there won't be misleading info...

PS. I believe you'll find a lot of hatred pointed toward XML in this thread eventually started by me :P
http://www.actionscript.org/forums/showthread.php3?t=195916
You are also welcome to search it for provocative quotes and learn those by heart :D