Session 10: Data exchange - syndication
XML
XML document objects, 15, 695-699, 1027
creating, 1074
searching, 1075
transforming, 1076
XML (Extensible Markup Language), 692-713
basics, 693
CDATA sections, 707
data, matching with XPath, 708-711
document objects (see XML document objects)
DOM nodes, 699-702
generating, 702-707
parsing with structure and array functions, 697
sending XML data, 461
special characters, 706
transforming with XSLT, 711-713
Verity filter, tweaking, 522
web services foundation, 744
XML Path (see XPath)
XmlChildPos( ), 1074
XmlElemNew( ), 1074
xmlElemNew( ), 706
XMLFormat( ), 84, 1074
XmlNew( ), 704, 1074
XmlParse( ), 1075
converting XML documents to XML document objects, 695
XmlSearch( ), 709, 1075
XmlTransform( ), 711, 1076
XPath (XML Path), matching XML data with, 708-711
XSL (Extensible Stylesheet Language), 711
XSLT (Extensible Stylesheet LanguageXML (Extensible Markup Language) is considered a language which in the future may replace HTML for coding web pages. It is, as HTML , a derived subset of SGML (Standard Generalized Markup Language) and permits a programmer to define new tags and their meaning for different applications.
The tags can be defined in a DTD (Document Type Definition), which may either be embedded in the XML file in which it is used, or, if the tags are used in several files, DTD may be in a separate file downloaded with the XML files and read by the browser. The presentation style of the XML file content can be separated from the structure of the file in a style sheet prepared by means of XSL (Extensible Style Language). XLL (Extensible Link Language), a language for defining hypertext links in XML web pages belongs also to the family.
The XML document object is a special data type in CFMX . An XML document can easily be converted to this data type by means of the function XmlParse() . A great advantage of the XML document object is that it can be processed by the ordinary CFMX structure functions.
An XML document must be strictly well-formed . It is well-formed if it is free of of syntax errors. If syntax errors exist in an XML document, it cannot be processed.
XML is an extensive topic which deserves its own course. In this course, we have space only to refer the interested student to the short introduction of XML in RBB , and to the many books issued in the recent years on the topic. In the remaining of this session, we shall discuss a technology for exchanging data between different types of computer platforms based on XML . This technology, WDDX , does not require any extensive knowledge about the XML language.
Web Distributed Data Exchange
WDDX (Web Distributed Data Exchange) is an open technology for exchanging all kinds of data types by means of an XML representation. It is intended to be used for exchanging data among applications implemented by different software languages, and run on different hardware platforms. WDDX is constructed on the simple assumption that data to be exchanged is ' serialized ' from the local language of the sender to a representation readable by all systems and ' deserialized ' to the foreign language of the receiver. The exchange requires that serialization and deserialization functions exist for each environment participating in the exchange. Required WDDX functions have already been prepared for many programming languages and can be downloaded freely from the net.
In CFMX , the serialization and deserialization are controlled by a special tag, < CFWDDX ACTION=".." INPUT=".." OUTPUT=".." > , which can be used without any knowledge of XML . The ACTION attribute can take 2 values in which we are interested: cfml2wddx is used for serialization, and wddx2cfml for decentralization (2 more will be discussed in the last session). Other languages/platforms have corresponding instructions, which permit each partner to use the instructions of her/his technology to serialize data to be sent and deserialize data received.
Data exchange between art galleries
The WDDX technology is demonstrated in the following scenario. Consider 2 cooperating Art Galleries , A and B , which have agreed to inform each other in text and images about their stocks of paintings at the end of each month. This kind of loose cooperation is often referred to as content syndication .
The following data about each painting should be included in the exchange:
- Identification
- Name of picture
- Name of artist
- Time at which the painting was completed
- Estimated value
- Picture of the painting
Each gallery has its own database not available on the web. A problem for the data exchange is that the partners have different hardware platforms , run different operating systems and database systems. Fortunately, WDDX modules exist for both system environments.
Figure 1 shows the data exchange scenario between the 2 galleries.
Implementation of the exchange
To demonstrate the WDDX data exchange, we consider the following templates:
The menu is quite ordinary and should not need any explanation:
- index.cfm generating menu for the application
- Form_store.cfm and store.cfm for packing and storing new pictures data
- Transmit.cfm for retrieving, and sending stored pictures data
- Packet.cfm for inspecting a received WDDX packet
- Table.cfm for unpacking and view the a received image data.
- <!--- index.cfm --->
- <div align="center">
- <h2><font color="Blue">Menu for WDDX example</font></h2>
- <table>
- <tr><td><a href="form_store.cfm">Store picture data in a database</a></td></tr>
- <tr><td><a href="transmit.cfm">Transmit data</a></td></tr>
- <tr><td><a href="table.cfm">See table</a> </td></tr>
- <tr><td><a href="packet.cfm">See packet</a></td></tr>
- </table>
- </div>
The form_store.cfm initiates the form for uploading a new picture from your client computer of to the server of the first gallery assuming you are in charge of this gallery and have acquired the pictured painting:
- <!--- form_store.cfm --->
- <center>
- <h2><font color="#0000FF">Storing picture data in a database</font></h2>
- <p>Select an image stored on your PC. It doesn't matter what you call the painting(image) or the artist's name.</p>
- <cfform action="store.cfm" method="post">
- <table>
- <tr><td>Picture name:</td><td><cfinput name="name" type="text"></td></tr>
- <tr><td>Picture artist:</td><td><cfinput name="artist" type="text"></td></tr>
- <tr><td>Picture created:</td><td><cfinput name="created" type="text"></td></tr>
- <tr><td>Picture value:</td><td><cfinput name="est_value" type="text"></td></tr>
- <tr><td>Picture file:</td><td><input name="picture" type="file" ></tr>
- <tr><td></td><td><input type="submit" value="Submit"></td></tr>
- </table>
- </cfform>
Figure 2 illustrates the use of the form which is trivial.
The store.cfm is more interesting. Line 2, uploads the selected picture from a users computer to the server of the first gallery and stores it in a temporary binary image file. The next statement reads this file into a variable called picture . Then a new structure, picture_data is defined in Line 4, and the structure is populated by Lines 5-9. Structure is a very convenient data type because it can be processed as a single object or variable. Our variable is picture_data .
- <--- store.cfm --->
- <cffile action="UPLOAD" filefield="form.picture" destination="#session.path#\temp.jpg" nameconflict="OVERWRITE">
- <cffile action="READBINARY" file="#session.path#\temp.jpg" variable="picture">
- <cfset picture_data=StructNew()>
- <cfset picture_data.name=#form.name#>
- <cfset picture_data.artist=#form.artist#>
- <cfset picture_data.created=#form.created#>
- <cfset picture_data.est_value=#form.est_value#>
- <cfset picture_data.picture=#picture#>
- <cfwddx action="cfml2wddx" input="#picture_data#" output="picture_packet">
- <cfif not IsWddx(#picture_packet#)>
- <p>Picture_packet is not a well-formed XML. </p>
- <cfabort>
- </cfif>
- <cfquery name="delete" datasource="#session.datasource#">
- DELETE FROM wddx
- </cfquery>
- <cfquery name="packet_in" datasource="#session.datasource#">
- INSERT INTO wddx(packet) Values('#picture_packet#')
- </cfquery>
- <center>
- <cfoutput>
- <p>Picture data structure has been successfully stored in the database.</p>
- </cfoutput>
- <p><a href="index.cfm">Return</a> to menu.</p>
- </center>
Line 10 uses the WDDX function to convert the object picture_data to a single text string, the WDDX packet picture_packet . This is an XML page and is checked in Lines 11-13 for being well-formed. An XML page not well-formed cannot be processed, and if so the process is aborted. As usual, session.path must be set in the Application.cfm pointing to the directory in which you store your WDDX example.
Lines 15-17 are included for this example to delete old paintings in the database. In a real applications, these lines would not be included. Lines 18-20 store all the painting data represented as a text string in a variable named packet in the table WDDX . This demonstrates a compact way of storing data in a database. Alternatively, the data could of course have been stored in a table with one variable for each painting attribute, which would have permitted searching in the database by attribute values.
To send a copy of the table to a collaborating gallery, we need to retrieve the packet from the database. Since it is already serialized before it was saved in the database, we may only want to test the packet again for well-formness before it is sent to the receiving gallery. The packet can be sent to the other gallery by means of the CFHTTP tag we already know from a previous session. To avoid working with 2 servers, we 'substitute' the transfer .by a remark tag and continue as if we are on the receiving server of the other gallery
The template transmit.cfm for the sending data from one gallery to another based on CFMX looks like this:
- <!--- transmit.cfm --->
- <cfquery name="packet_out" datasource="#session.datasource#">
- SELECT packet FROM wddx
- <cfquery>
- <cfif Not IsWDDX(#packet_out.packet#)>
- <;p>Packet_out.packet is not a well-formed XML</p>
- <cfabort>
- </cfif>
- <!--- Code for packet transfer to the other server --->
- <cffile action="write" file="#session.path#\packet.txt" output="#packet_out.packet#">
- <center>
- <h2><font color="#0000FF">Dump of transmitted packet</font></h2>
- <cfoutput>
- <cfdump var="#packet_out#" >
- </cfoutput>
- </center>
Lines 2-4 retrieves the packet(s) naming the query object packet_out . Since a WDDX packet is an XML file, it is again tested for well-formness. Line 9 is the substitute for the real transmission. In a real application, Line 9 must be replaced by CFHTTP and CFHTTPPAR tags to initiate the transfer to the server of the second gallery where Line 10 takes care of storing the received packet in a text file, packet.txt , at the other server.
Lines 11-16 applies the CFDUMP tag which displays the complex WDDX packet object by components. Figure 3 illustrates the result generated by this tag. Note that this dump is not the the packet string representation, but an interpretation of the packet content.
The packet text string itself can be displayed by the template packet.cfm :
- <!--- packet.cfm --->
- <center> <h2><font color="#0000FF">Display of WDDX packet</font></h2>
- <cffile action="read" file="#session.path#\packet.txt" variable="packet2">
- <cfoutput > <textarea rows="15" cols="70" wrap="virtual"> #packet2#</textarea>
- </cfoutput>
- </center>
The XML file for representation of the image used in the example is illustrated in Figure 4 . You can explore the tags and representations. You can for example se that the whole image used in the example is represented by a string of 22065 characters.
We shall return to the DTD for the WDDX packets in a moment. Notice that the variables represented in the packet are ordered by the values of the variables, not by their names. A whole painting structure is represented in a text string with a surprisingly low number of bytes.
The last template, table.cfm , let you see the picture data after it has been deserialized at the simulated receiving end. When received, the packet was saved in packet.txt as an XML file. This file is read and transformed to a variable picture_data2 by Line 2 and deserialized by Line 3 to a structure object, deserialized_packet , with five variable. In a real application, the CFWDDX function in Line 3 must be replaced by the WDDX function corresponding to the receiving gallery's platform.
We have now the structure object. To display the picture, we must first save the picture component in Line 4 so it can be binary read in Line 13..
In the remaining lines the content of the structure is displayed for the user.
- <!--- table.cfm --->
- <cffile action="read" file="#session.path#\packet.txt" variable="picture_data2">
- <cfwddx action="wddx2cfml" input="#picture_data2#" output="deserialized_packet">
- <cffile action="WRITE" file="#session.path#\picture_received.jpg" output="#deserialized_packet.picture#" nameconflict="overwrite">
- <center>
- <cfoutput>
- <h2><font color="Blue">Received picture data</font></h2>
- <table>
- <tr><td>Name: </td><td>#deserialized_packet.name#</td></tr>
- <tr><td>Artist:</td><td> #deserialized_packet.artist#</td></tr>
- <tr><td>Created:</td> <td>#deserialized_packet.created#</td></tr>
- <tr> Value: #deserialized_packet.est_value#</td></tr>
- <p><img src="#session.url#/picture_received.jpg" height="300" width="250" border="0" ></p>
- </table>
- </cfoutput>
- </center>
To be able to exchange the pictures, both galleries must have the templates discussed above supplemented by the CFHTTP tag to send the WWDX packets to each other. The final result from our example for this exchange process is shown in Figure 5 . Remember that you must set the session.url also in the Application.cfm of the example.
DTD for WDDX
Referring to the introduction of this session, you may wonder how the document type definition for the WDDX looks. Here is a link to the DTD file defining the language of WDDX . If you activate this link, the WDDX document type definition is displayed for you by means of an XML document object. Recall that the use of the WDDX technology does not require that you know anything about neither this DTD , XML nor XML document objects .Exercises
a. Copy the displayed templates, complete the example with the statements required for sending the picture data to a remote host (for example another student), and test out your application.
b. Download the WDDX software needed for receiving packets in a JAVA environment, and see if you succeed to deserialize the packets sent from the ColdFusion host in a JAVA environment.
c. For simple mass data exchange, a less general technology based on XML can be used. Consider the requirements for a scenario you know, and use RBB as a guide to planning you own data exchange design.
Link to the session example.
Link to the session test.
You are reminded to turn to the Assignment section, complete and submit your project proposal. You are required to both submit your proposal and pass the Test to obtain access to Session 11.
Link to the session assignment.
Nesting custom tags
A custom tag can call other custom tags from within it's body text, thereby nesting tags. ColdFusion uses nested tags such as cfgraph and cfgraphdata , cfhttp and cfhttppam , and cftree and cftreeitem . The ability to nest tags allows you to provide similar functionality.
Steve McKean
UH-Email
CT FORUM CF
user - enter
Steve McKean
UH-Email
CT FORUM CF
user - enter
CFMX HISTORY RESOURCES
OBJECTIVES
Implementation aspects: