|
Example: using XML in a ColdFusion application
The following shows how
you can use XML to represent data, and how ColdFusion can use XML
data in an application. Although the example is too simple to be
used in an application without substantial changes, it presents
some of the common uses of XML with ColdFusion.
The example receives an order in the form of an XML document,
processes it, and generates an XML receipt document. In this case,
the order document is in a file, but it could be received as the
result of an HTTP request, or retrieved using cfpop, cfftp,
or other methods. The ColdFusion page does the following with the
order:
Generates a query object from an XML document.
Queries a database table to determine the order discount
percentage to use.
Uses a query of queries to calculate the total price, then
calculates the discounted price.
Generates the receipt as an XML document.
This example displays the results of the processing steps to
show you what has been done.
The XML documentThe order.xml document has the following
structure:
The root element is named order and has
one attribute, id.
One customer element exists with firstname, lastname, and
accountnum attributes. The customer element does not have a body
One items element exists that contains multiple item elements
Each item element has an id attribute and contains a name,
quantity, and unitprice element. The name, quantity, and unitprice
elements contain their value as body text.
The following
order.xml document works correctly with the information in the cfdocexamples
database:
<order id="4323251">
<customer firstname="Philip" lastname="Cramer" accountNum="21"/>
<items>
<item id="43">
<name>
Large Hammer
</name>
<quantity>
1
</quantity>
<unitprice>
15.95
</unitprice>
</item>
<item id="54">
<name>
Ladder
</name>
<quantity>
2
</quantity>
<unitprice>
40.95
</unitprice>
</item>
<item id="68">
<name>
Paint
</name>
<quantity>
10
</quantity>
<unitprice>
18.95
</unitprice>
</item>
</items>
</order>
The ColdFusion pageThe ColdFusion page looks like the following:
<!--- Convert file to XML document object --->
<cffile action="read" file="C:\CFusion\wwwroot\examples\order.xml" variable="myxml">
<cfset mydoc = XmlParse(myxml)>
<!--- Extract account number --->
<cfset accountNum=#mydoc.order.customer.XmlAttributes.accountNum#>
<!--- Display Order Information --->
<cfoutput>
<b>Name=</b>#mydoc.order.customer.XmlAttributes.firstname#
#mydoc.order.customer.XmlAttributes.lastname#
<br>
<b>Account=</b>#accountNum#
<br>
<cfset numItems = ArrayLen(mydoc.order.items.XmlChildren)>
<b>Number of items ordered=</b> #numItems#
</cfoutput>
<br><br>
<!--- Process the order into a query object --->
<cfset orderquery = QueryNew("item_Id, name, qty, unitPrice") >
<cfset temp = QueryAddRow(orderquery, #numItems#)>
<cfloop index="i" from = "1" to = #numItems#>
<cfset temp = QuerySetCell(orderquery, "item_Id",
#mydoc.order.items.item[i].XmlAttributes.id#,#i#)>
<cfset temp = QuerySetCell(orderquery, "name",
#mydoc.order.items.item[i].name.XmlText#, #i#)>
<cfset temp = QuerySetCell(orderquery, "qty",
#mydoc.order.items.item[i].quantity.XmlText#, #i#)>
<cfset temp = QuerySetCell(orderquery, "unitPrice",
#mydoc.order.items.item[i].unitprice.XmlText#, #i#)>
</cfloop>
<!--- Display the order query --->
<cfdump var=#orderquery#>
<br><br>
<!--- Determine the discount --->
<cfquery name="discountQuery" datasource="cfdocexamples">
SELECT *
FROM employee
WHERE Emp_Id = #accountNum#
</cfquery>
<cfset drate = 0>
<cfif #discountQuery.RecordCount# is 1>
<cfset drate = 10>
</cfif>
<!--- Display the discount rate --->
<cfoutput>
<b>Discount Rate =</b> #drate#%
</cfoutput>
<br><br>
<!--- Compute the total cost and discount price--->
<cfquery name="priceQuery" dbType="query">
SELECT SUM(qty*unitPrice)
AS totalPrice
FROM orderquery
</cfquery>
<cfset discountPrice = priceQuery.totalPrice * (1 - drate/100)>
<!--- Display the full price and discounted price --->
<cfoutput>
<b>Full Price=</b> #priceQuery.totalPrice#<br>
<b>Discount Price=</b> #discountPrice#
</cfoutput>
<br><br>
<!---Generate an XML Receipt --->
<cfxml variable="receiptxml">
<receipt num = "34">
<cfoutput>
<price>#discountPrice#</price>
<cfif drate GT 0 >
<discountRate>#drate#</discountRate>
</cfif>
</cfoutput>
<itemsFilled>
<cfoutput query="orderQuery">
<name> #name# </name>
<qty> #qty# </qty>
<price> #qty*unitPrice# </price>
</cfoutput>
</itemsFilled>
</receipt>
</cfxml>
<!--- Display the resulting receipt --->
<cfdump var=#receiptxml#>
Reviewing the codeThe following table describes the CFML code and
its function. For the sake of brevity, it does not include code
that displays the processing results.
Code
|
Description
|
<cffile action="read" file="C:\CFusion\wwwroot\examples\order.xml" variable="myxml">
<cfset mydoc = XmlParse(myxml)>
<!--- Extract account number --->
<cfset accountNum=#mydoc.order.customer.XmlAttributes.accountNum#>
|
Reads the XML from a file and convert it
to an XML document object.
Sets the accountNum
variable from the customer entry’s accountnum attribute.
|
<cfset orderquery = QueryNew("item_Id, name, qty, unitPrice") >
<cfset temp = QueryAddRow(orderquery, #numItems#)>
<cfloop index="i" from = "1" to = #numItems#>
<cfset temp = QuerySetCell(orderquery, "item_Id",
#mydoc.order.items.item[i].XmlAttributes.id#,#i#)>
<cfset temp = QuerySetCell(orderquery, "name",
#mydoc.order.items.item[i].name.XmlText#, #i#)>
<cfset temp = QuerySetCell(orderquery, "qty",
#mydoc.order.items.item[i].quantity.XmlText#, #i#)>
<cfset temp = QuerySetCell(orderquery, "unitPrice",
#mydoc.order.items.item[i].unitprice.XmlText#, #i#)>
</cfloop>
|
Converts the XML document object into a
query object.
Creates a query with columns for the item_id,
name, qty, and unitPrice values for each item.
For each XML
item entry in the mydoc.order.items entry, fills one row of the
query with the item’s id attribute and the text in the name, quantity,
and unitprice entries that it contains.
|
<cfquery name="discountQuery" datasource="cfdocexamples">
SELECT *
FROM employee
WHERE Emp_Id = #accountNum#
</cfquery>
<cfset drate = 0>
<cfif #discountQuery.RecordCount# is 1>
<cfset drate = 10>
</cfif>
|
If the account number is the same as an
employee ID in the cfdocexamples database Employee table, the query
returns one record. and RecordCount equals 1. In this case, sets
a discount rate of 10%. Otherwise, sets a discount rate of 0%.
|
<cfquery name="priceQuery" dbType="query">
SELECT SUM(qty*unitPrice)
AS totalPrice
FROM orderquery
</cfquery>
<cfset discountPrice = priceQuery.totalPrice * (1 - drate/100)>
|
Uses a query of queries with the SUM operator
to calculate the total cost before discount of the ordered items,
then applies the discount to the price. The result of the query
is a single value, the total price.
|
<cfxml variable="receiptxml">
<receipt num = "34">
<cfoutput>
<price>#discountPrice#</price>
<cfif drate GT 0 >
<discountRate>#drate#</discountRate>
</cfif>
</cfoutput>
<itemsFilled>
<cfoutput query="orderQuery">
<name> #name# </name>
<qty> #qty# </qty>
<price> #qty*unitPrice# </price>
</cfoutput>
</itemsFilled>
</receipt>
</cfxml>
|
Creates an XML document object as a receipt.
The receipt has a root element named receipt, which has the receipt
number as an attribute. The receipt element contains a price element
with the order cost and an itemsFilled element with one item element
for each item.
|
|