Inside Coldfusion MX

Now that you have a working understanding of XML and how to create it, you need to know how to actually do something with it. To be able to do anything with XML, you need to be able to access or work with data in an XML document (or stream). ColdFusion MX enables you to do that through a series of ColdFusion tags and functions (which we will review) that allow you to parse, search, transform, edit, and so on. In this section, we are going to look at parsing XML documents we have already created.

It is possible to parse XML using ColdFusion, various functions, and regular expressions, but you would have limited capability to parse the documents and validate against a DTD. Furthermore, using ColdFusion regular expressions or some other method of parsing XML using string functions is so slow as to be unusable in most cases. Unless you only need one piece of data from a XML document, this might be an unworkable solution.

We have managed to create XML documents in the preceding listings, so let's try reading in an XML document from a file, changing it into an XML document object, and then accessing the data and doing something with it.

Let's look at the code first, as shown in Listing 19.7.

Listing 19.7 parseXML.cfm

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <title>Parse Price List</title> </head> <body> <cffile action="read" file="#ExpandPath(".")#/pricelist.xml" variable="XMLFileText"> <! - XMLParse function turns our text into a XML docuemnt object or ColdFusion Structure -> <cfset myXMLDocument=XmlParse(XMLFileText)> <cfoutput> Product name: #myXMLDocument.XmlRoot.XmlChildren[1].XmlChildren[1].XmlText#<br> Product SKU: #myXMLDocument.XmlRoot.XmlChildren[1].XmlChildren[2].XmlChildren [1]. XmlText#<br> Product Description: #myXMLDocument.XmlRoot.XmlChildren[1].XmlChildren[2].XmlChildren [2]. XmlText#<br> Product Price: #myXMLDocument.XmlRoot.XmlChildren[1].XmlChildren[2].XmlChildren [4]. XmlText#<br> </cfoutput> </body> </html>

The first thing we do in this code, as you can see, is use CFFILE to read in our XML document, and we use the new XML function XMLParse to parse the XML and convert it into an XML document object. After that, we introduce some new concepts to you that you should actually be familiar with from Chapter 7, "Complex Data Types." To extract data from a ColdFusion XML document object, we need to access the XML document object in much the same way we would access a ColdFusion structure.

As we already know, an XML document object is a series of structures, with the main structure holding one root element structure. The root element can have any number of nested element structures. Each element structure represents an XML tag (start tag/end tag set) and all its contents; it can contain additional element structures. This structure models the XML document object model (DOM), which we will talk about in much more detail in the Chapter 20, "Advanced XML."

To access the information, we just need to figure out where in the structure (from Figure 19.3) is the data we need to access (or we can look at the XML in Figure 19.2 and attempt this). One way to do this "by hand" is to count the nodes or child elements from the root element to access a specific piece of data from the structure. To get the name of the product, we need to do this:

<cfoutput> #myXMLDocument.XmlRoot.XmlChildren[1].XmlChildren[1].XmlText# </cfoutput>

This is one way to traverse the structure. It basically tells ColdFusion that you want to access the structure at the first child element of the first child element branch of the root element.

The output of this will then be as follows:

Product name: ColdFusion MX

This is the name of the first product in our XML document. To get access to the product's SKU/product code, you would use the following inside a cfoutput:

#myXMLDocument.XmlRoot.XmlChildren[1].XmlChildren[2].XmlChildren[1].XmlText#

This would produce the following:

Product SKU: CFMX2002

The next lines of code just change which node ColdFusion is going to access to retrieve data from. For product description, we just use the following:

#myXMLDocument.XmlRoot.XmlChildren[1].XmlChildren[2].XmlChildren[2].XmlText#<br>

For product price, we write the following:

#myXMLDocument.XmlRoot.XmlChildren[1].XmlChildren[2].XmlChildren[4].XmlText#<br>

You should be able to see by looking at the CFDUMP of pricelist how we are extracting data from each node in the DOM object. Try experimenting with this code and changing the value of the various XML childern to see what happens. For example, change Listing 19.7 to look like Listing 19.8.

Listing 19.8 modified_parseXML.cfm

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <title>Parse Price List</title> </head> <body> <cffile action="read" file="#ExpandPath(".")#/pricelist.xml" variable="XMLFileText"> <! - XMLParse function turns our text into a XML docuemnt object or ColdFusion Structure -> <cfset myXMLDocument=XmlParse(XMLFileText)> <cfoutput> Product name: #myXMLDocument.XmlRoot.XmlChildren[2].XmlChildren[1].XmlText#<br> Product SKU: #myXMLDocument.XmlRoot.XmlChildren[2].XmlChildren[2].XmlChildren [1]. XmlText#<br> Product Description: #myXMLDocument.XmlRoot.XmlChildren[2].XmlChildren [2].XmlChildren[2]. XmlText#<br> Product Price: #myXMLDocument.XmlRoot.XmlChildren[2].XmlChildren[2].XmlChildren [4]. XmlText#<br> </cfoutput> </body> </html>

Now execute this template. Was it what you expected? Most likely, you have an idea now how accessing DOM nodes works, but there is a lot more to it and it can be confusing. Don't worry if you are a little confused; in Chapter 20, we are going to go into great detail about how to access the DOM object. For now, though, we need to cover some more information about the basic structure of the ColdFusion XML object.

Let's look at all the different structure variables/entries that an XML document has that you can use to access an XML document object. At the top level, the XML document object has the three entries shown in Table 19.6.

Table 19.6. Top-Level Entries for the XML Document Object

Entry Name

Type

Description

XmlRoot

Element

The root element of the document.

XmlComment

String

A string made of the concatenation of all comments on the document. This string does not include comments inside document elements.

XmlDocType

XmlNode

The DocType attribute of the document. This entry only exists if the document specifies a DocType. This entry does not appear when cfdump displays an XML element structure.

Each XML element has the entries shown in Table 19.7.

Table 19.7. Element Structure

Entry Name

Type

Description

XmlName

String

The name of the element.

XmlNsPrefix

String

The prefix of the namespace.

XmlNsURI

String

The URI of the namespace.

XmlText

String

A string made up of the concatenation of all text and CDATA text in the element, but not inside any child elements.

XmlComment

String

A string made up of the concatenation of all comments inside the XML element, but not inside any child elements.

XmlAttributes

Structure

The specific element's attributes, as a structure of name-value pairs.

XmlChildren

Array

The specific element's children elements as an array.

XmlParent

XmlNode

The parent DOM node of this element.

Note: XMLParent does not appear when CFDUMP displays an XML element structure.

XmlNodes

Array

An array of all the XmlNode DOM nodes contained in this element.

Note: XmlNodes does not appear when cfdump displays an XML element structure.

Table 19.8 lists the contents of an XML DOM node structure.

Table 19.8. XML DOM Node Structure

Entry Name

Type

Description

XmlName

String

The node name. For nodes such as Element or Attribute, the node name is the element or attribute name.

XmlType

String

The node XML DOM type, such as Element or Text.

XmlValue

String

The node value. This entry is used only for Attribute, CDATA, Comment, and Text type nodes.

Table 19.9 lists the contents of the XmlName and XmlValue fields for each node type that is valid in the XmlType entry. The node types correspond to the objects types in the XML DOM hierarchy.

Table 19.9. XmlType Name and Value Pairs

Node Type

XmlName

XmlValue

Cdata

#cdata-section

Content of the CDATA section

Comment

#comment

Content of the comment

Element

Tag name

Empty string

Entityref

Name of entity referenced

Empty string

PI (processing instruction)

Target entire content excluding the target

Empty string

Text

#text

Content of the text node

Entity

Entity name

Empty string

Notation

Notation name

Empty string

Document

#document

Empty string

Fragment

#document-fragment

Empty string

Doctype

Document type name

Empty string

Note

If you need to get an element's attributes, use the element structure's XMLAttributes structure. Although XML attributes are nodes on the DOM tree, ColdFusion does not expose them as XML DOM node data structures.

Категории