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.
Each XML element has the entries shown in Table 19.7.
Table 19.8 lists the contents of an XML DOM node structure.
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.
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. |