- Feature Articles
- CodeSOD
- Error'd
- Forums
-
Other Articles
- Random Article
- Other Series
- Alex's Soapbox
- Announcements
- Best of…
- Best of Email
- Best of the Sidebar
- Bring Your Own Code
- Coded Smorgasbord
- Mandatory Fun Day
- Off Topic
- Representative Line
- News Roundup
- Editor's Soapbox
- Software on the Rocks
- Souvenir Potpourri
- Sponsor Post
- Tales from the Interview
- The Daily WTF: Live
- Virtudyne
Admin
The one line:
"Each time is this style and is customized for the particular...."
Should read:
"Each time in this style and is customized for the particular..."
I hate grammatical errors. I do apologize.
Admin
I love how one of the variables is named "kount"
Admin
All,
Forgive me for my XML ignorance, but what is the main problem with the code as posted?
Seeya
Matthew
Admin
Besides the complete unmaintainibility and that they didn't use a library to write the XML?
Admin
<DATA name="Question" value="
Forgive me for my XML ignorance, but what is the main problem with the code as posted?"></DATA>
<DATA name="Answer" value="For the same reason this is bad, without reading the name and having special processing for each different name you cannot use this data"></DATA>
-----------
<QUESTION>Isn't this easier to read?</QUESTION>
<ANSWER>Yes</ANSWER>
Admin
Nice comment Anon!! :-D
Admin
That "kount" variable is EVERYWHERE. I HATE IT. I'm not sure of it's origin. It may be because the person who is using it has a name that starts with a k. Either way it along with this "XML" gives you an indication of the quality of code I deal with daily.. :)
Admin
"That "kount" variable is EVERYWHERE. I HATE IT. I'm not sure of it's origin."
I'd have to say that the dude came from Fortran where integer vars were named i-k. The perverse verboseness also leans towards an old Fortran coder.
Admin
"count" is a reserved word in some systems. So maybe this person is just used to that. (Along with the same style of programming s/he used when they were 13.)
Admin
What's really annoying is I know EXACTLY why this code looks this way. Because he's lazy and he investigated XML to this level. He figured out JUST enough to get this. When if he would have spent a few more days or DAY, he would have seen a whole other world of XML. I mean Borland C++ Builder 6 has all the tools BUILT in.. ARggghhhHHHhhHHH!!! :)
Admin
I love meaningless tag names. Whee!
Admin
I suggest replacing the 'kount' variable in the entire solution to 'cunt'.
That way you avoid any conflicts with reserved words and finally put something worth it all inside that code.
Admin
XML sucks.
Admin
XML rocks!
Admin
Shall I be honest? Okay... I've done the same once to generate XML output. And actually, it's not that bad if it gets the job done. I had two options for the project I was playing with. Either I generated a whole XML schema, used some wizard to generate Delphi code from it, include it into my project and have a bloated piece of software because all the libraries I needed to include in it. Or I used simple WriteLn statements just to write the XML as pure text to a file, without the need of any additional libraries, keeping the code plain and simple.
I chose the latter not just because it's not that much work but also because the XML format isn't that difficult to understand. You could add an XML library and set up all the XML nodes in it that you need but hey... This generates valid XML code too...
Besides, this code would be much longer and slower if he had used an XML library. Why? Well, he would need to add one line for every node he needs to add. He then needs one line to add the properties to the nodes and perhaps a third line to assign a value to the property. Maybe even more, all to create a single node. And the XML library just has to build it up all in-memory until it's finished before the whole thing can be written to disk so a large XML document would eat up lots of memory. This method is faster and requires less memory. Okay, it requires a bit more maintenance but hey... Look at the source. You can easily read the whole XML structure in there...
However, I would probably have used:
AG->RptList->Add (tmp.sprintf (" <Data name="%s" value="%s"></Data>", SomeName, SomeValue));
And SomeName and SomeValue would just be retrieved from some simple array or table. That way you can just walk through the array in a for-next loop and you would not need this much code to write every line. If you consider it a WTF, then it's a WTF because he doesn't use this simple trick but instead writes every statistical value on a separate line.
Do you really think it would become more effective if you'd use a DTD or schema with some additional XML library linked to it all? I think it would just become slower...
Admin
It's all very very simple. All you need to do is...
1. Drop all of your values into a class because that keeps them all in one place and it's a lot easier to maintain them.
2. Design these classes so that they contain information in them about the actual class, kind of like instructions for ''slightly less adept people'' but actually coded into the class. Reasons for this will become clear.
3. Write your own parser that will ''read'' any of the classes from point 1 that have been designed in the way from point 2. The parser doesn't give a flying f@!* what is in the class or even how big it is, it just reads through it and translates it to XML. (There's the reason for the coded instructions!)
And there you go, you've got an XML file that EXACTLY represents your data that you can then use a schema with although it's not neccessary if all of the classes (point 2) have been designed with the same format.
Bonus points too, you can use the same data with a stylesheet to make your data look ''pretty'' and more readable.
Brucie Bonus Points!!!: you can use the same process to put the data from the XML file into the classes. All because the classes don't care what is in the XML, the XML doesn't care what is in the objects, and as for the parser, that just doesn't care.
Not only does this keep all of your data and output unified and easily mantainable but it is also crazy fast considering what you are doing. If you put the effort in at the start, you can reap the rewards later.[8-|]
Admin
The way to do this kind of thing is:
1 - build methods to convert your data objects into XML. If your language has anything like java reflection, you only need one method. In fact, if you have existing SOAP libraries or something like java.beans.XMLEncoder, you don't need to write anything at all.
2 - use XSLT to transform this full data dump into your custom format. XSLT is the right tool for the job of converting XML from one form to another.
We use this method to present data objects in a tree as a cut-down user friendly view or a full technical view. The data transforms for our various value objects are in BusinessRendition.xsl and TechnicalRendition.xsl, and the full unprocessed XML is what we put in our audit tables. The same code works for "view a user before saving" and "view a user as at a previous point in its history". Sweet.
Admin
Sweet indeed.
Admin
Admin
Katja, the point is that this defeats the purpose of using XML in the first place. If you don't want an XML library, then just don't use XML. XML has, in that regard, no advantage over any other structured format. The way this file is written, it could just as well be an INI file. It would make no difference.
Another point is that, even if you don't use an XML library, that's still no reason not to output proper tag names instead of the meaningless "data".
What's wrong with
AG->RptList->Add(tmp.sprintf(" <%s>%s</%s>", SomeName, SomeValue, SomeName));
? (Aside from the parameter repetition - Boost's Format library would help there.)
This way, someone who does use an XML library will have a far easier time making sense of the whole thing.
Admin
CornedBee, using an XML library isn't always the best solution. Especially if you're going to create a huge XML file or if you need some very fast code. Keep in mind that you don't write code to have something that looks nice. You write code to get a job done, preferably fast too.
For whatever reason, an XML file apparantly needed to be generated. Maybe because it's combined with a stylesheet to generate some nicely formatted output. Or perhaps because the XML data needs to be imported by some other tool that wants to import it. In general, XML is generated to help with client-server solutions and in those cases an XML library would be slower and more bloated than just generating the output this way.
And XML can be formatted any way you like but I think that in this case the output must meet a certain format. Nothing wrong to generate a different output but some other tool is probably expecting a certain format while importing the data again. Ever looked at an ADO recordset if you save it as an XML file? Lots of those "Data" tags in those. And why not? It IS data. It has a name and it has a value.
Admin
Katja: how on earth do you have XML experience too?
You're proficient in everything. Is that even possible? You say you work for your Dad and are a student. There's no way you can have this much knowledge about so many various topics!
Admin
And on top of that you are a well-rounded individual with knowledge of arts, culture, and even the animal kingdom?
I just don't get Katja. Maybe I'm envious?
Admin
Katja's right here. Fundamentally, XML is a transport medium, its goal to allow transportation of data, both the values and (more importanly) the MEANING of the values, from one system to another. The means used to create, parse and manipulate the data are not germaine to the question. SAX and DOM methods merely provide two standardized toolsets for playing with what is, in the end, a text file. DTDs and schemas are merely contracts concerning the content -- interfaces, if you will. Neither a DTD nor a schema is actually required to make use of XML, although they do reduce the chances of misunderstanding to nearly nil. Nor is a DOM or SAX library actually required for reading/manipulating an XML document -- they just reduce the chances of creating an incorrect representation of the data on the receiving system. As for creating a document/file and throwing it to the world, anything that puts one character in front of the other in the order required fits the bill. DOM will always be a relative memory hog, and the performance is orders of magnitude worse than simple text output -- provided that simple text output can be realised from the data without building an equivalent in-memory structure for nested elements. All any system needs in order to participate in the XML/Web Services world is the ability to listen for requests on an appropriate port, the ability to parse text, the ability to create text, and the ability to reply over the same port. The rest is padding to isolate you from the greasy wheels and protect you from yourself.
Admin
<FONT style="BACKGROUND-COLOR: #efefef">Using simple IO to generate XML compliant output is fine. The DOM exists to provide a parser/navigator/query/etc system for dealing with an unknown document / document with some crap added.</FONT>
With a .Net focus it is a lot easier (if you have your data in a System.Data.DataSet, which is likely) to serialise it with a soap formatter and then XSLT it into your final format. This is about 5 lines from memory.
Benefit of this method is you can pull the data out the database, and slap it out to a Excel XML file (with pretty formatting). Keeps the accountants happy, and the code is simpler than other methods. The XSLT is fairly easy to write also, you can make the template wysiwyg in Excel, and save it out, edit it to XSLT and blammo.
Admin
Stan has a good point, XML was designed as a transport medium. Katja has a point to, an XML document can be what ever you want it to be, but I think everyone is getting a little of point here. Now I don't want to alienate anyone here but everyone at one time or another is responsible for thinking that the way they do things is the best way.
And that is EVERYBODY, me included, probably more than most!
I think the point of the original WTF was the fact that the code looks like it been written by someone who has only got to page 47 of the book of how to write crap unreadable, unmaintainable, stupid code.
I mean god damn, should anything change with the system that this came from and the person who originaly wrote it wasn't working for the company anymore and the changes were business critical. Would you like the job of changing it if you've never seen it before?
The thing that I really love about the code is the developer has even put padding spaces in before the data elements to make the output file a little more readable. Maybe it was someone else though, I'm inclined to thing it might have been.
Admin
Yes, it's possible. And I don't have that much experience with it, but I did learn most of my programming skills while XML was becoming popular. You can say I grew up with it, just like others have grown up with HTML and other webrelated languages. I'm not very good at it, but it's just that I try to learn a bit of as many topics as possible so I can easily change my future profession from e.g. software developer to webdeveloper or system administrator or whatever. I'm just trying to broaden my horizons.
Besides, my dad uses XML for years now as a file format to store configuration data... :-)
Admin
Knowledge of arts, culture and animal kingdom? I just have knowledge of Google...[:P]
Admin
CannonFodda has a good point too. True, the original code doesn't look very clean, especially since it's just one element that is repeated over and over again. You'd just wonder if he could not have stored that data in an array or list or database or whatever and then enumerate through this list in a loop, with just a single line that writes the element, with name and value extracted from this list. That would reduce the risks of any spelling errors.
Yet I don't see anything much wrong with the original concept. It's lots of code, but at least it gets the job done fast, with not much memory requirements. Ideal if the final XML document would be a huge monstruous file to begin with...
Has this code been written by someone with barely no XML experience? Or has it been written by someone with a lot of experience? Someone who knew that using an XML library would cost too much in performance...
Of course, if the XML scheme is to change, it means a lot of rewrites have to be done. Then again, in such a case you could still keep the old code and use an XSLT file to convert it to whatever new format you like. Why fix it if it's not broken? It generates valid XML data, so it should be fine. And it should perform bloody fast too.
Admin
What ever the system is that produces the XML may perform very well indeed, but without a schema/DTD or even XSL document, the outputed XML file would be usless to everything but a very tightly coupled system.
This is because you would have to either know what each element is and call it by it's attributes, which means you end up doubling your work if there is any changes as you have to change the input system and the output system, be that a different system on a seperate architecture or a simple report. Or you could load the whole file and enumerate through it building up the structure as you go, which would be very slow and still very perceptable to change.
Admin
I don't think generating a DTD or schema based upon this XML file isn't so difficult to begin with. And since this format has been predetermined you don't really need a schema anymore. All you would need is an XSLT file to convert it to some other XML format. Just look at the file format! He could have used an INI file instead to store all this information. But okay, XML is a bit neater and is easier to manipulate since you can use XSLT with it. The output is just a very simple, flat format that can easily be modified. No need to invent new tags for new values since you can simply add them by providing the name and value attribute. It seems to me a simple solution to store named values.
I'm not sure what those values actually are, btw. But it seems to me that they just have to be tempoary stored. The original source for this data seems as unstructured as the data itself. It all seems to come from a record called stats. So if you think about it, the XML file is just a representation of this record... Just one record with a gazillion number of fields. And whomever wrote this piece of code did not want to make this record more structured...
Admin
Maybe they should have, maybe that information was on page 48 oh the book they were using.
It seems the developer did not anticipate the system that this came from ever changing, which is a bad idea, or maybe never anticipated anyone else having to maintain or upgrade the code, which is also a bad idea.
All I'm saying that for something that is quick and dirty and will not be implemented for a long time then the code is fine. I would've probably done something similar myself if it was only going to be used for a short time. But for something that is going to be used in a production environment for any length of time, that has the possibilty of be updated or changed (especially by other developers) then a little more time should have been spent on the development. This is what saves time later.
Admin
Well, this code could have been a Quick and Dirty method before someone else decided that it should have a less temporary use. Then again, I've said it before and just say it again... This code is bloody fast compared to any other solution that you might choose that would require an XML library. If this is part of some server-side code then I would actually prefer this code over the use of an XML library because well... It just gets the job done fast, with a small memory imprint. Exactly what you want on a server that has to server thousands of visitors every hour...
I know it looks ugly. I know it seems very hard to maintain. I don't know why the writer didn't just use an array to store all data in but hey. It works! And if there are no flaws in the code, it would perform better than any XML library would. It's just that there's a slightly bigger risk that it has a bug. (Spelling errors) And yes, it is a bit harder to maintain too.
When you develop software, my dad keeps saying that you always have to judge performance with ease of maintenance. Especially with server-side programming. Not that I've done much server-based stuff, though. But my dad does, so he tries to find a nice balance between it all. The time it costs in maintenance can easily be compensated by the time you save while the software is operational.
Did I already mention that this WTF code is actually quit fast? I think it depends a bit on the XML library that you use but it could be about 400% faster. And will require a lot less memory during processing. For a server-side solution, this is exactly what you would want. Lots of speed and a low memory consumation. Which is why I still don't consider it a big WTF.
But hey, as I said, this XML structure just seems to be based on a single record with a gazillion fields. I think this record structure should be optimized first before you optimize the XML stuff. Because basically, the XML file is just a representation of this single record...
Admin
Performance over maintenance is a good point, but the WTF code is obviously for a report structure of some kind, and in the business world, reports tend to often change and sometimes quite drastically. And as the code is replicated in 20+ custom formats, that’s a lot of maintenance.
As for performance, this is a basic text dump (just in XML format) be it to a solid state medium or to memory. Now as the WTF code is just a possible snippet of a possible larger document, who knows what the memory consumption is of the process. If the document was much larger then the memory cost would also be much larger, especially if the process was compiling the data into memory and then writing it to a disk or transmitting it across a network. And on that point, there is one flaw with the code, why does it contain end tags if none of the elements have children. Thats just more processing where it's not needed.
If this was a much larger process than is actually shown then something like the SAX parser would possible handle it in a much better way and produce more solid and maintainable solution than the basic text dump. As for client-server processing, servers are designed to be hammered by user requests and there for are more powerful systems. If there not, then that is not a developers problem, that’s a hardware problem.
An even better solution would be to have something like an OLAP Cube sat over the data so the response times would be tiny in comparison to producing the report on the fly, the only bottle-neck then would be the speed it takes to write the data to a disk or transmit it over a network, but again that is a hardware issue. Also the OLAP Cube idea is a completely different route and off the point of XML and was probably not implemented due to cost and/or other hardware/software configurations.
Admin
You can be right but I won't easily admit that... [:P]
If I just look at this code snippet, all I see is that some in-memory record structure is converted to XML. This record structure just happens to be a flat one. As a result, the resulting XML is also quite flat and pretty easy to write. No deep layers of data or whatever. Just a list of fields with values.
Personally, I think the real WTF is that this data isn't stored a bit more structured in-memory, so the XML output would also represent this more structured stuff. And since this record structure is just a simple collection of data fields, I'd assume a simple array structure would be far more useful in this case. Makes it easier to enumerate the values, makes it easier to do all kinds of things with it too. Of course it's not a pretty way to generate XML data but hey, the background information that this XML is based upon is seriously lacking any structure too. Garbage in, garbage out.
You're right about the missing end tags since technically, they could be removed. But is there really no difference between <element></element> and <element/>? You could assume that the first option has an empty value while in the second version, no value has been assigned to the element. The difference between empty and non-assigned can be pretty big for some people.
Admin
<element/> would be far better than <element></element> because technical the element is empty, it's just the element contains attributes, it doesn't contain any data
<FONT style="BACKGROUND-COLOR: #ffffff">But your right about the structure of the data in memory, I would not be suprised if the data from the record came from multiple sources and was actually flattened out into a single record, the field names would definatly support this therory. So that would mean even more processing time.[:D]</FONT>
</FONT>Admin
A schema/DTD can only tell you what it looks like; it can't tell you what to do with it. A "tightly coupled" (for varying definitions of "tightly") is required nevertheless.
Consider an XHTML document. A DTD will tell you that TDs are inside TRs which are inside TABLEs, but it won't give you any information at all on how that's supposed to be rendered.
Admin
Good point. I did not even consider that. [:$]
But perhaps not completely, since the code could be using a XSLT file to transform whatever data it receives into the tightly coupled XML file that it needs. That way you'd have a loose XML file, an XSLT file that can recognize it and convert it to something else and your application that reads this something else. I believe this is why there are so many socalled mapping tools right now, that can be used to convert one XML file to another XML file.
But again, for this you don't even need a DTD or schema, although the mapping tool might use a schema to design some XML map. Change the XML format and all you technically would need to change too is the map.
XML is not a miraculous and complex technology. It's just a plain text file format, structured in some way. It's not XML itself that is so powerful. It's the tools that are using the XML protocol that really add the power.
Admin
I wish somebody would plaster this on the walls of every programming department.
Most people are under the impression that XML is this "magical" solution that will solve every technological problem.
We can fix that...just use XML...we can do that...just use XML...
<FONT color=#000080 size=6>WTF</FONT>
Admin
All you people have a real problem with XML!!!
It is a fantastic magical solutions for all our problems, I mean, have you not seen the fluffy little bunnies that hop around you when your using it???
Or is that just me?[:)]
Admin
Gotta love the "<Data>" tag. What I would have done instead is:
<?xml version="1.0"?>
<rootnode>
<parentnode>
<childnode>
<childnode>
...
Admin
... An interesting approach. However you forget the need to call this from non-xml code. I think this handles it better:
<FONT size=2></FONT><FONT color=#800000 size=2><FONT size=2></FONT><FONT color=#800000 size=2><FONT face="Courier New"> class</FONT></FONT><FONT face="Courier New"><FONT size=2> Name </FONT><FONT color=#800000 size=2>extends</FONT></FONT><FONT face="Courier New"><FONT size=2> </FONT><FONT color=#bb7977 size=2>String</FONT></FONT><FONT face="Courier New"><FONT size=2> </FONT><FONT color=#800080 size=2>{}</FONT></FONT><FONT size=2><FONT face="Courier New"> </FONT>
</FONT><FONT color=#800000 size=2><FONT face="Courier New"> class</FONT></FONT><FONT face="Courier New"><FONT size=2> Value </FONT><FONT color=#800000 size=2>extends</FONT></FONT><FONT face="Courier New"><FONT size=2> </FONT><FONT color=#bb7977 size=2>String</FONT></FONT><FONT face="Courier New"><FONT size=2> </FONT><FONT color=#800080 size=2>{} </FONT></FONT>
<FONT face="Courier New"><FONT color=#800080 size=2>
<FONT face="Courier New" color=#808030></FONT><FONT size=2><FONT size=2><FONT face="Courier New" color=#808080> /* use this method as a template. Create other reports by naming </FONT></FONT><FONT face="Courier New"><FONT color=#800080 size=2><FONT face="Courier New"><FONT color=#800080 size=2><FONT color=#808080>
<FONT size=2><FONT face="Courier New"> methods getXML2, getXML3 and populating appropriate data arrays */</FONT></FONT></FONT><FONT face="Courier New"><FONT color=#800080 size=2><FONT face="Courier New"><FONT color=#800080 size=2> </FONT></FONT></FONT></FONT></FONT></FONT></FONT></FONT><FONT face="Courier New"><FONT color=#800080 size=2><FONT size=2>
</FONT></FONT></FONT><FONT color=#bb7977 size=2><FONT face="Courier New"> </FONT></FONT></FONT></FONT><FONT color=#800000 size=2><FONT face="Courier New">public</FONT></FONT><FONT face="Courier New"><FONT size=2> </FONT><FONT color=#bb7977 size=2>String</FONT></FONT><FONT face="Courier New"><FONT size=2> getXML1</FONT><FONT color=#808030 size=2>()</FONT><FONT size=2> </FONT><FONT color=#800080 size=2>{ </FONT></FONT><FONT size=2>
</FONT><FONT color=#bb7977 size=2><FONT face="Courier New"> Object</FONT></FONT><FONT face="Courier New"><FONT color=#808030 size=2>[]</FONT><FONT size=2> data </FONT><FONT color=#808030 size=2>=</FONT><FONT size=2> </FONT><FONT color=#800000 size=2>new</FONT></FONT><FONT face="Courier New"><FONT size=2> </FONT><FONT color=#bb7977 size=2>Object</FONT></FONT><FONT face="Courier New"><FONT color=#808030 size=2>[]</FONT><FONT color=#800080 size=2>{ </FONT></FONT><FONT size=2>
</FONT><FONT color=#800000 size=2><FONT face="Courier New"> new</FONT></FONT><FONT face="Courier New"><FONT size=2> Name</FONT><FONT color=#808030 size=2>(</FONT><FONT color=#0000e6 size=2>"value1"</FONT><FONT color=#808030 size=2>),</FONT><FONT size=2> </FONT><FONT color=#800000 size=2>new</FONT></FONT><FONT face="Courier New"><FONT size=2> Value</FONT><FONT color=#808030 size=2>(</FONT><FONT color=#0000e6 size=2>"value1"</FONT><FONT color=#808030 size=2>), </FONT></FONT>
</FONT><FONT size=3><FONT face="Courier New"><FONT color=#008000><FONT color=#008000> ... snip</FONT></FONT><FONT color=#008000> <FONT size=2><FONT size=3>...</FONT> </FONT></FONT></FONT></FONT>
<FONT color=#800000 size=2><FONT face="Courier New"> new</FONT></FONT><FONT face="Courier New"><FONT size=2> Name</FONT><FONT color=#808030 size=2>(</FONT><FONT color=#0000e6 size=2>"value403032"</FONT><FONT color=#808030 size=2>),</FONT><FONT size=2> </FONT><FONT color=#800000 size=2>new</FONT></FONT><FONT face="Courier New"><FONT size=2> Value</FONT><FONT color=#808030 size=2>(</FONT><FONT color=#0000e6 size=2>"value403032"</FONT><FONT color=#808030 size=2>) </FONT></FONT><FONT size=2>
</FONT><FONT color=#800080 size=2><FONT face="Courier New"> };</FONT> </FONT><FONT size=2>
</FONT><FONT color=#800000 size=2><FONT face="Courier New"> return</FONT></FONT><FONT face="Courier New"><FONT size=2> getXML</FONT><FONT color=#808030 size=2>(</FONT><FONT size=2>data</FONT><FONT color=#808030 size=2>)</FONT><FONT color=#800080 size=2>; </FONT></FONT><FONT size=2>
</FONT><FONT color=#800080 size=2><FONT face="Courier New"> }</FONT> </FONT>
<FONT color=#800000 size=2><FONT face="Courier New"> public</FONT></FONT><FONT face="Courier New"><FONT size=2> </FONT><FONT color=#bb7977 size=2>String</FONT></FONT><FONT face="Courier New"><FONT size=2> getXML</FONT><FONT color=#808030 size=2>(</FONT><FONT color=#bb7977 size=2>Object</FONT></FONT><FONT face="Courier New"><FONT color=#808030 size=2>[]</FONT><FONT size=2> data</FONT><FONT color=#808030 size=2>)</FONT><FONT size=2> </FONT><FONT color=#800080 size=2>{
<FONT size=2><FONT face="Courier New" color=#808080> // we use Strings because we can add them. </FONT></FONT></FONT></FONT><FONT face="Courier New"><FONT color=#800080 size=2><FONT face="Courier New"><FONT color=#800080 size=2><FONT color=#808080>
<FONT size=2><FONT face="Courier New"> // StringBuffer.append() has more characters so is less efficient.</FONT></FONT></FONT><FONT face="Courier New"><FONT color=#800080 size=2><FONT face="Courier New"><FONT color=#800080 size=2> </FONT></FONT></FONT></FONT></FONT></FONT></FONT></FONT><FONT face="Courier New"><FONT color=#800080 size=2><FONT size=2>
</FONT></FONT></FONT><FONT color=#bb7977 size=2><FONT face="Courier New"> String</FONT></FONT><FONT face="Courier New"><FONT size=2> xml </FONT><FONT color=#808030 size=2>=</FONT><FONT size=2> </FONT><FONT color=#800000 size=2>new</FONT></FONT><FONT face="Courier New"><FONT size=2> </FONT><FONT color=#bb7977 size=2>String</FONT></FONT><FONT face="Courier New"><FONT color=#808030 size=2>(</FONT><FONT color=#0000e6 size=2>"<?xml version="</FONT><FONT color=#008000 size=2>1.0</FONT><FONT color=#0000e6 size=2>"?>"</FONT><FONT color=#808030 size=2>)</FONT><FONT color=#800080 size=2>; </FONT></FONT><FONT size=2>
<FONT face="Courier New"> xml </FONT></FONT><FONT face="Courier New"><FONT color=#808030 size=2>+=</FONT><FONT size=2> </FONT><FONT color=#800000 size=2>new</FONT></FONT><FONT face="Courier New"><FONT size=2> </FONT><FONT color=#bb7977 size=2>String</FONT></FONT><FONT face="Courier New"><FONT color=#808030 size=2>(</FONT><FONT color=#0000e6 size=2>"<rootnode>"</FONT><FONT color=#808030 size=2>)</FONT><FONT color=#800080 size=2>; </FONT></FONT><FONT size=2>
<FONT face="Courier New"> xml </FONT></FONT><FONT face="Courier New"><FONT color=#808030 size=2>+=</FONT><FONT size=2> </FONT><FONT color=#800000 size=2>new</FONT></FONT><FONT face="Courier New"><FONT size=2> </FONT><FONT color=#bb7977 size=2>String</FONT></FONT><FONT face="Courier New"><FONT color=#808030 size=2>(</FONT><FONT color=#0000e6 size=2>"</FONT><FONT color=#0f69ff size=2>\t</FONT><FONT color=#0000e6 size=2><parentnode>"</FONT><FONT color=#808030 size=2>)</FONT><FONT color=#800080 size=2>; </FONT></FONT><FONT size=2>
<FONT face="Courier New"> xml </FONT></FONT><FONT face="Courier New"><FONT color=#808030 size=2>+=</FONT><FONT size=2> </FONT><FONT color=#800000 size=2>new</FONT></FONT><FONT face="Courier New"><FONT size=2> </FONT><FONT color=#bb7977 size=2>String</FONT></FONT><FONT face="Courier New"><FONT color=#808030 size=2>(</FONT><FONT color=#0000e6 size=2>"</FONT><FONT color=#0f69ff size=2>\t\t</FONT><FONT color=#0000e6 size=2><childnode>"</FONT><FONT color=#808030 size=2>)</FONT><FONT color=#800080 size=2>; </FONT></FONT><FONT size=2>
<FONT face="Courier New"> xml </FONT></FONT><FONT face="Courier New"><FONT color=#808030 size=2>+=</FONT><FONT size=2> </FONT><FONT color=#800000 size=2>new</FONT></FONT><FONT face="Courier New"><FONT size=2> </FONT><FONT color=#bb7977 size=2>String</FONT></FONT><FONT face="Courier New"><FONT color=#808030 size=2>(</FONT><FONT color=#0000e6 size=2>"![CDATA["</FONT><FONT color=#808030 size=2>)</FONT><FONT color=#800080 size=2>; </FONT></FONT><FONT size=2>
</FONT><FONT color=#800000 size=2><FONT face="Courier New"> for</FONT></FONT><FONT face="Courier New"><FONT size=2> </FONT><FONT color=#808030 size=2>(</FONT><FONT color=#bb7977 size=2>int</FONT><FONT size=2> i </FONT><FONT color=#808030 size=2>=</FONT><FONT size=2> </FONT><FONT color=#008c00 size=2>0</FONT><FONT color=#800080 size=2>;</FONT><FONT size=2> i </FONT><FONT color=#808030 size=2><</FONT><FONT size=2> data</FONT><FONT color=#808030 size=2>.</FONT><FONT size=2>length</FONT><FONT color=#800080 size=2>;</FONT><FONT size=2> i</FONT><FONT color=#808030 size=2>++)</FONT><FONT size=2> </FONT><FONT color=#800080 size=2>{ </FONT></FONT><FONT size=2>
<FONT face="Courier New"> xml </FONT></FONT><FONT face="Courier New"><FONT color=#808030 size=2>+=</FONT><FONT size=2> </FONT><FONT color=#800000 size=2>new</FONT></FONT><FONT face="Courier New"><FONT size=2> </FONT><FONT color=#bb7977 size=2>String</FONT></FONT><FONT face="Courier New"><FONT color=#808030 size=2>(</FONT><FONT color=#0000e6 size=2>"</FONT><FONT color=#0f69ff size=2>\"</FONT><FONT color=#0000e6 size=2>"</FONT><FONT color=#808030 size=2>)</FONT><FONT color=#800080 size=2>; </FONT></FONT><FONT size=2>
<FONT face="Courier New"> xml </FONT></FONT><FONT face="Courier New"><FONT color=#808030 size=2>+=</FONT><FONT size=2> </FONT><FONT color=#800000 size=2>new</FONT></FONT><FONT face="Courier New"><FONT size=2> </FONT><FONT color=#bb7977 size=2>String</FONT></FONT><FONT face="Courier New"><FONT color=#808030 size=2>(</FONT><FONT size=2>data</FONT><FONT color=#808030 size=2>[</FONT><FONT size=2>i</FONT><FONT color=#808030 size=2>].</FONT><FONT size=2>toString</FONT><FONT color=#808030 size=2>())</FONT><FONT color=#800080 size=2>; </FONT></FONT><FONT size=2>
</FONT><FONT color=#800000 size=2><FONT face="Courier New"> if</FONT></FONT><FONT face="Courier New"><FONT size=2> </FONT><FONT color=#808030 size=2>(</FONT><FONT size=2>data</FONT><FONT color=#808030 size=2>[</FONT><FONT size=2>i</FONT><FONT color=#808030 size=2>]</FONT><FONT size=2> </FONT><FONT color=#800000 size=2>instanceof</FONT></FONT><FONT face="Courier New"><FONT size=2> Name</FONT><FONT color=#808030 size=2>) </FONT></FONT><FONT size=2>
<FONT face="Courier New"> xml </FONT></FONT><FONT face="Courier New"><FONT color=#808030 size=2>+=</FONT><FONT size=2> </FONT><FONT color=#0000e6 size=2>"</FONT><FONT color=#0f69ff size=2>\"</FONT><FONT color=#0000e6 size=2>,</FONT><FONT color=#0f69ff size=2>\"</FONT><FONT color=#0000e6 size=2>"</FONT><FONT color=#800080 size=2>; </FONT></FONT><FONT size=2>
</FONT><FONT color=#800000 size=2><FONT face="Courier New"> else</FONT></FONT><FONT face="Courier New"><FONT size=2> </FONT><FONT color=#800000 size=2>if</FONT></FONT><FONT face="Courier New"><FONT size=2> </FONT><FONT color=#808030 size=2>(</FONT><FONT size=2>data</FONT><FONT color=#808030 size=2>[</FONT><FONT size=2>i</FONT><FONT color=#808030 size=2>]</FONT><FONT size=2> </FONT><FONT color=#800000 size=2>instanceof</FONT></FONT><FONT face="Courier New"><FONT size=2> Value</FONT><FONT color=#808030 size=2>) </FONT></FONT><FONT size=2>
<FONT face="Courier New"> xml </FONT></FONT><FONT face="Courier New"><FONT color=#808030 size=2>+=</FONT><FONT size=2> </FONT><FONT color=#0000e6 size=2>"</FONT><FONT color=#0f69ff size=2>\"\n</FONT><FONT color=#0000e6 size=2>"</FONT><FONT color=#800080 size=2>; </FONT></FONT><FONT size=2>
</FONT><FONT color=#800080 size=2><FONT face="Courier New"> }</FONT> </FONT><FONT size=2>
<FONT face="Courier New"> xml </FONT></FONT><FONT face="Courier New"><FONT color=#808030 size=2>+=</FONT><FONT size=2> </FONT><FONT color=#800000 size=2>new</FONT></FONT><FONT face="Courier New"><FONT size=2> </FONT><FONT color=#bb7977 size=2>String</FONT></FONT><FONT face="Courier New"><FONT color=#808030 size=2>(</FONT><FONT color=#0000e6 size=2>"]]"</FONT><FONT color=#808030 size=2>)</FONT><FONT color=#800080 size=2>; </FONT></FONT><FONT size=2>
<FONT face="Courier New"> xml </FONT></FONT><FONT face="Courier New"><FONT color=#808030 size=2>+=</FONT><FONT size=2> </FONT><FONT color=#800000 size=2>new</FONT></FONT><FONT face="Courier New"><FONT size=2> </FONT><FONT color=#bb7977 size=2>String</FONT></FONT><FONT face="Courier New"><FONT color=#808030 size=2>(</FONT><FONT color=#0000e6 size=2>"</FONT><FONT color=#0f69ff size=2>\t\t</FONT><FONT color=#0000e6 size=2></childnode>"</FONT><FONT color=#808030 size=2>)</FONT><FONT color=#800080 size=2>; </FONT></FONT><FONT size=2>
<FONT face="Courier New"> xml </FONT></FONT><FONT face="Courier New"><FONT color=#808030 size=2>+=</FONT><FONT size=2> </FONT><FONT color=#800000 size=2>new</FONT></FONT><FONT face="Courier New"><FONT size=2> </FONT><FONT color=#bb7977 size=2>String</FONT></FONT><FONT face="Courier New"><FONT color=#808030 size=2>(</FONT><FONT color=#0000e6 size=2>"</FONT><FONT color=#0f69ff size=2>\t</FONT><FONT color=#0000e6 size=2></parentnode>"</FONT><FONT color=#808030 size=2>)</FONT><FONT color=#800080 size=2>; </FONT></FONT><FONT size=2>
<FONT face="Courier New"> xml </FONT></FONT><FONT face="Courier New"><FONT color=#808030 size=2>+=</FONT><FONT size=2> </FONT><FONT color=#800000 size=2>new</FONT></FONT><FONT face="Courier New"><FONT size=2> </FONT><FONT color=#bb7977 size=2>String</FONT></FONT><FONT face="Courier New"><FONT color=#808030 size=2>(</FONT><FONT color=#0000e6 size=2>"</rootnode>"</FONT><FONT color=#808030 size=2>)</FONT><FONT color=#800080 size=2>; </FONT></FONT><FONT size=2>
</FONT><FONT color=#800000 size=2><FONT face="Courier New"> return</FONT></FONT><FONT face="Courier New"><FONT size=2> xml</FONT><FONT color=#800080 size=2>; </FONT></FONT><FONT size=2>
</FONT><FONT color=#800080 size=2><FONT face="Courier New"> }</FONT></FONT></FONT>
Not only can we call this from code, it allows us to add more data in the future by simply extending the string class again and it also frees us from inefficient DOM or SAX libraries!