It puts the X in Ajax: How to structure XML for interactive Web apps

This article is excerpted from Ajax for Web Application Developers, copyright 2007, published last month by Sams Publishing. Reprinted with permission, all rights reserved.

XML (Extensible Markup Language) is a popular choice for Ajax, simply because it is the standard intermediate language that all programming languages are able to share. It is also supported both on the server side and client side, which makes it the most flexible solution. XML is essentially a custom tag-based structure that you, the developer, define. XML's tag-based structure is similar to that of HTML, except that HTML has predefined tags that represent its structure, such as the head, the body, tables and so on. The following is an extremely simple example of an HTML table, which could easily be translated or used as XHTML:

<p><table><tr><td></td></tr></table></p>

XML can be passed between the front end and the back end for easy communication of multiple languages. Having this common language between the front end and the back end is extremely powerful. It enables us to create direct connections from the GUI to a server-side language and, ultimately, if desired, a database. Communicating with XML between the GUI and the front end allows for complete separation of the two application layers. Separation of the GUI and the back-end logic is extremely important because it enables us to have a completely decoupled application in which GUI developers can work on the front end, while the back-end developers work on the back end.

This might seem like common sense, but it is an approach lacking in many companies. It keeps specific parts of the application separated for easier management, and allows teams or individual developers to focus on the layer that is in need of growth. Not only is this approach ideal for teams of developers, it is also important for any individual developer who might be working on every part of the application. With this structure, an individual developer can focus on specific layers of the application without interfering or having to make changes to the adjacent layers.

XML formatting is trivial, but there are important principles to consider when planning a solution. Imagine having to format e-mail data into a structure that could be requested through an Ajax engine and displayed with client-side JavaScript objects. When architecting this structure, we want to keep in mind that we may use it in multiple objects or locations of the application and should therefore keep it as abstract as possible. We will start by defining the main elements that will create this structure.

Elements

XML is composed of custom tags called elements, which are defined in the architecture phase of a Web application. They can represent any name, value or data type that will be used in your application. When creating an XML structure, you become the architect of your application, deciding what data you will need to display certain items on the screen, or what response should happen based on a user's interaction.

It is important to keep our structures as abstract as possible by not naming items specific to the target application, but there are often unique situations that prevent us from being as abstract as we need to be. In these cases, it is not beneficial to spend the extra time to make our XML structure abstract because it might not even be necessary to reuse the XML data in multiple areas of the application. With that said, it is possible to be abstract with our email XML sample and it will be reused in other aspects of the application. The following is a usable XML format, but not an extremely scalable or reusable option:

<categories>
    <From/>
    <Subject/>
    <Date/>
</categories>

In order to keep these categories abstracted, we will change the names of the elements to category:

<categories>
    <category>From</category>
    <category>Subject</category>
    <category>Date</category>
</categories>

This option provides the flexibility that allows us to add additional categories with ease. There are many reasons that this option is more scalable; an important one to remember is the fact that we can add a new category without having to change the structure of our XML data. This is why it is so flexible and a more scalable option than the previous example. Also, if we create object-oriented objects to display the data, we do not need to add additional parsing and display code to handle the new elements. This is why it is so important to architect the solution with abstract structures that can be scalable and easily ported to other applications or objects.

For instance, imagine that you need to display the same list of categories in two different ways, such as in a data grid and an e-mail preview. This same set of elements can be used in both objects, which eliminates any redundancies in code from our application. Although elements are what make XML, there is a limit to what can be achieved with elements alone. Let's take a look at attributes and how they help us add additional information to our XML data.

Attributes

XML attributes are additional properties that can be added to your elements to provide more information specific to the structure. From the e-mail sample, let's focus on an e-mail element. An e-mail has many attributes, such as an action that is triggered when the e-mail is selected, and an icon association, such as a sealed or opened envelope, based on the read status of the e-mail. In order to represent our e-mails in the XML, we will create a group of items that can eventually become a collection of objects or an array when they are parsed on the client side. This is where we will add our action and icon attributes. Attributes are easy additions to elements. Take a look at the following to get an idea of how we will add the action and icon attributes to an XML element.

An Abstract List of Items (email.xml)

<items action="alert('Grace Hopper');" icon="img/mail.gif">
    <item>
    <item>BUG Found]]>
    <item>2006-03-31 09:27:26
</items>

There are some issues that are very important to be aware of when using attributes, especially in large applications where making a mistake in the architecture stage can create havoc when scaling. One of the biggest issues with attributes is not having the ability to add multiple values in one attribute. This could create an issue if you later decide that you need to have more than one instance of a specific detail that was already defined as an attribute, leaving you or your fellow developers having to make changes in multiple locations where there are references to the attributes.

Another important issue, and one that we will discuss a solution for in the next section, is adding HTML to your XML. HTML cannot be added to attributes because it will create an invalid structure. The only way to add HTML to an XML structure is within an element. It is much safer to add an element than an attribute because if you realize that you made a mistake and forgot to format the element properly to contain HTML, you can always reformat it later to accept HTML without breaking any code that might be referencing it. In order to add HTML to elements so that it is readable by the programming language that is parsing it and does not break the validation of the XML, we need to add CDATA tags to the element tags.

CDATA

CDATA makes XML - and, ultimately, the Web applications that use it - extremely powerful by allowing us to add HTML to elements. The HTML can then be used to display formatted data directly into a DOM (Document Object Model) element in our Ajax application front end. When XML is parsed by the programming language that we are using, the value between the element tags is also parsed. The following example shows a group of <item> elements that are nested in an </items> element:

<items action="alert('Grace Hopper');" icon="img/mail.gif">
    <item>Grace Hopper</item>
    <item>BUG Found</item>
    <item>2006-03-31 09:27:26</item>
</items>

These nested elements need to be parsed into subelements by the parser in order to be interpreted by the programming language as child nodes, for example. This means that nesting HTML tags inside of XML elements will not work because the parser will see these elements as nested or child elements of the parent element rather than HTML tags, which will make the XML invalid, causing parsing errors or unexpected results. The following XML will parse with the HTML bold tag (</b>) as an XML element because the parser will see the bold tags as nested XML tags rather than HTML:

<item><b>BUG Found</b></item>

In order to add HTML to the XML element, we are required to use CDATA. XML parsers do not parse the data immediately following these tags, leaving us with a valid XML structure and ultimately the HTML format that we would like to display in the page. The following code shows valid XML with HTML tags nested in an element using CDATA:

<item> <![CDATA[<b>BUG Found</b>]]></item>

When this data is parsed by the client-side scripting language, which in our case will be JavaScript, the HTML will render as is between the tags. For example, the text value of BUG Found will display as bold text to the user in the GUI if we write the data to the document. The data can be written to the document by simply targeting an HTML tag using the DOM and appending the value with JavaScript's intrinsic innerHTML property, or we could simply use document.write(); to write the value directly to the location in which we place this line of code.

When planning the format and tag names that you will be using in your XML, it is important to keep a number of things in mind. For instance, it is usually beneficial to have unique names for elements that are at different depths in your file. This will eliminate parsing issues when using JavaScript's intrinsic getElementsByTagName method. Using this method will return an array of all the elements by the name that you specify without looking at the depth in which they reside.

One issue that this could cause is that groups of values from different depths that do not belong together can be combined into one array that does not delineate the correct location of the data, causing a parsing nightmare for you or your fellow developers. There are ways to parse data that use nested tags with duplicate names, such as targeting with the childNodes property, but this can become difficult and lengthen the development process. You could also create an object that has methods for parsing specific items by name at specific depths, such as XPath does in other languages, or use attributes to distinguish different nodes with the same name. But for our purposes, we will simply define our structure in a way that we do not have to worry about such issues.

There are fairly standard ways of parsing XML with different languages, but parsing XML with JavaScript is a bit different. As I have mentioned, JavaScript has an intrinsic method named getElementsByTagName, which can target a group of elements directly by name and allow us access to them so that we can easily parse element or attribute values. This method will either return a single element or a group of elements by the tag name specified as the parameter, as in the following example:

response.getElementsByTagName('items');

When the method finds a group of elements, it will return an array of childNodes that you will need to parse to receive their inner nodeValues.

For more on Ajax, see:

  •  Hands On: Understanding AJAX

  •  So how do you code an AJAX Web page?

  •  AJAX QuickStudy

This article is excerpted from Ajax for Web Application Developers, copyright 2007, published last month by Sams Publishing. Reprinted with permission, all rights reserved.

This is an awesome caption!

Copyright © 2006 IDG Communications, Inc.

How to supercharge Slack with ‘action’ apps
  
Shop Tech Products at Amazon