Presentation is loading. Please wait.

Presentation is loading. Please wait.

How to: Read, Write, and Use XML in CFMX

Similar presentations


Presentation on theme: "How to: Read, Write, and Use XML in CFMX"— Presentation transcript:

1 How to: Read, Write, and Use XML in CFMX
ColdFusion + XML How to: Read, Write, and Use XML in CFMX Erik Goodlad 1

2 Session Overview XML Overview CFMX Built-In XML Functions
ColdFusion XML Object Reading & Writing XML to File System Using XML with Web Services Common XML Tasks Using XML as a Data Storage On-line Resources

3 XML Overview

4 What is XML? From Wikipedia, the free encyclopedia: The Extensible Markup Language (XML) is a W3C-recommended general-purpose markup language. The XML recommendation specifies both the structure of XML, and the requirements for XML processors. XML is considered "general-purpose" because it enables anyone to originate and use a markup language for many types of applications and problem domains. Numerous formally defined markup languages are based on XML, such as RSS, MathML, GraphML, XHTML, Scalable Vector Graphics, MusicXML, and thousands of others. XML's primary purpose is to facilitate the sharing of data across different information systems, particularly systems connected via the Internet. It is a simplified subset of Standard Generalized Markup Language (SGML), and is designed to be relatively human-legible. XML is an open, fee-free standard. Bunch of words here, main points: - “general-purpose” because you can mark-up almost any data model you want - opposed to RSS which is XML, but it might be in a particular RSS format - open standard, no fee

5 What does XML look like? <?xml version="1.0" encoding="UTF-8"?>
<recipe name="bread" prep_time="5 mins" cook_time="3 hours"> <title>Basic bread</title> <ingredient amount="3" unit="cups">Flour</ingredient> <ingredient amount="0.25" unit="ounce">Yeast</ingredient> <ingredient amount="1.5" unit="cups" state="warm">Water</ingredient> <ingredient amount="1" unit="teaspoon">Salt</ingredient> <instructions> <step>Mix all ingredients together, and knead thoroughly.</step> <step>Cover with a cloth, and leave for one hour in warm room.</step> <step>Knead again, place in a tin, and then bake in the oven.</step> </instructions> </recipe> Manually parsing big text files with Mid() and Find() can be really difficult

6 XML Pros Human & Machine readable Supports Unicode
Can represent the basic data structures: Records, Lists, and Trees Strict syntax Plain text files

7 XML Cons XML syntax is redundant, too verbose
Redundancy may affect efficiency through higher storage, transmission and processing costs No native support for specifying data- types

8 Can we avoid using XML? A spotlight search on my MacBook returned 18,337 results for XML OSX uses XML .plist files for system settings

9 Firefox’s bookmarks.xml
<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE xbel PUBLIC "+//IDN python.org//DTD XML Bookmark Exchange Language 1.0//EN//XML" " <title>Bookmarks</title> <info><metadata owner="Mozilla" BookmarksToolbarFolder="rdf:#$FvPhC3"/></info> <bookmark id="rdf%3A#$1g21S3" href=""> <title>Apple Movie Trailers</title> <info><metadata owner="Mozilla" FeedURL=" </bookmark> <folder id="rdf%3A#$FvPhC3"> <title>Bookmarks Toolbar Folder</title> <desc>Add bookmarks to this folder to see them displayed on the Bookmarks Toolbar</desc> <bookmark id="rdf%3A#$4ucgD" href=" <title>CacheFly</title> <info><metadata owner="Mozilla" Icon="data:image/bmp;base64,Qk04AgAAAAAAADYAAAAoAA"/></info> </bookmark> <bookmark id="rdf%3A#$xXbYu3" href=" <title>Movies</title> </bookmark> <bookmark id="rdf%3A#$04GiT3" href=" <title>Measure Map</title> <info><metadata owner="Mozilla" Icon="data:image/x-icon;base64,AAABAAEAEBAQAAEABAAoAQ"/></info> </bookmark> <bookmark id="rdf%3A#$CO7yR" href=" <title>Google</title> <info><metadata owner="Mozilla" ShortcutURL="g" Icon="data:image/x-icon;base64,AAABAA"/></info> </bookmark> </folder></xbel>

10 Firefox’s bookmarks.xml
<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE xbel PUBLIC "+//IDN python.org//DTD XML Bookmark Exchange Language 1.0//EN//XML" " <title>Bookmarks</title> <info><metadata owner="Mozilla" BookmarksToolbarFolder="rdf:#$FvPhC3"/></info> <bookmark id="rdf%3A#$1g21S3" href=""> <title>Apple Movie Trailers</title> <info><metadata owner="Mozilla" FeedURL=" </bookmark> <folder id="rdf%3A#$FvPhC3"> <title>Bookmarks Toolbar Folder</title> <desc>Add bookmarks to this folder to see them displayed on the Bookmarks Toolbar</desc> <bookmark id="rdf%3A#$4ucgD" href=" <title>CacheFly</title> <info><metadata owner="Mozilla" Icon="data:image/bmp;base64,Qk04AgAAAAAAADYAAAAoAA"/></info> </bookmark> <bookmark id="rdf%3A#$xXbYu3" href=" <title>Movies</title> </bookmark> <bookmark id="rdf%3A#$04GiT3" href=" <title>Measure Map</title> <info><metadata owner="Mozilla" Icon="data:image/x-icon;base64,AAABAAEAEBAQAAEABAAoAQ"/></info> </bookmark> <bookmark id="rdf%3A#$CO7yR" href=" <title>Google</title> <info><metadata owner="Mozilla" ShortcutURL="g" Icon="data:image/x-icon;base64,AAABAA"/></info> </bookmark> </folder></xbel> RSS Feed (LiveMark) Favicon Shortcut Key

11 iTune’s Library XML <?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" " <plist version="1.0"> <dict> <key>Application Version</key><string>7.1.1</string> <key>Music Folder</key><string>file://localhost/Users/errorik/Music/iTunes/iTunes%20Music/</string> <key>Tracks</key> <key>152</key> <key>Track ID</key><integer>152</integer> <key>Name</key><string>Not Capable Of Love</string> <key>Artist</key><string>The Ataris</string> <key>Album</key><string>Rock Express 701R</string> <key>Genre</key><string>Rock</string> <key>Size</key><integer> </integer> <key>Total Time</key><integer>211121</integer> <key>Track Number</key><integer>5</integer> <key>Date Added</key><date> T16:24:00Z</date> <key>Play Count</key><integer>5</integer> <key>Play Date</key><integer> </integer> <key>Play Date UTC</key><date> T06:03:45Z</date> <key>Location</key><string>file://localhost/Users/errorik/Music/iTunes/iTunes%20Music/The%20Ataris/Rock%20Express%20701R/05%20Not%20Capable%20Of%20Love.mp3</string> </dict> </plist>

12 iTune’s Library XML Apple plist XML format uses naming standard
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" " <plist version="1.0"> <dict> <key>Application Version</key><string>7.1.1</string> <key>Music Folder</key><string>file://localhost/Users/errorik/Music/iTunes/iTunes%20Music/</string> <key>Tracks</key> <key>152</key> <key>Track ID</key><integer>152</integer> <key>Name</key><string>Not Capable Of Love</string> <key>Artist</key><string>The Ataris</string> <key>Album</key><string>Rock Express 701R</string> <key>Genre</key><string>Rock</string> <key>Size</key><integer> </integer> <key>Total Time</key><integer>211121</integer> <key>Track Number</key><integer>5</integer> <key>Date Added</key><date> T16:24:00Z</date> <key>Play Count</key><integer>5</integer> <key>Play Date</key><integer> </integer> <key>Play Date UTC</key><date> T06:03:45Z</date> <key>Location</key><string>file://localhost/Users/errorik/Music/iTunes/iTunes%20Music/The%20Ataris/Rock%20Express%20701R/05%20Not%20Capable%20Of%20Love.mp3</string> </dict> </plist> Apple plist XML format uses naming standard to specify data types

13 CFEclipse Snippet XML <?xml version="1.0" encoding="utf-8"?><snippet filetemplate="false" extension="cfm"><name>HTML Skeleton</name><help>Creates an HTML Skeleton Page</help><starttext><![CDATA[<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" " <meta http-equiv="Content-Type" content="text/html; charset=iso "> <title>Untitled Document</title></head>]]></starttext><endtext><![CDATA[</body></html>]]></endtext></snippet>

14 CFEclipse Snippet XML CDATA for passing strings with <TAGS>
<?xml version="1.0" encoding="utf-8"?><snippet filetemplate="false" extension="cfm"><name>HTML Skeleton</name><help>Creates an HTML Skeleton Page</help><starttext><![CDATA[<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" " <meta http-equiv="Content-Type" content="text/html; charset=iso "> <title>Untitled Document</title></head>]]></starttext><endtext><![CDATA[</body></html>]]></endtext></snippet> CDATA for passing strings with <TAGS>

15 /.’s RSS Feed <?xml version="1.0" encoding="UTF-8"?>
<rdf:RDF xmlns:rdf=" xmlns=" xmlns:slash=" xmlns:feedburner=" <channel rdf:about=" <title>Slashdot</title> <link> <description>News for nerds, stuff that matters</description> <items> <rdf:Seq> <rdf:li rdf:resource=" /> <rdf:li rdf:resource=" /> </rdf:Seq> </items> <image rdf:resource=" /> <textinput rdf:resource=" /> </channel> <image rdf:about=" <url> </image> <item rdf:about=" <title>Apple's Move May Make AAC Music Industry Standard</title> <link> <description>stivi writes "BusinessWeek has up an article about a war: a standards war...</description> <slash:department>razors-and-razorblades</slash:department> <slash:section>apple</slash:section> <slash:comments>38</slash:comments> <slash:hit_parade>38,36,30,25,4,4,1</slash:hit_parade> <feedburner:origLink> </item>

16 /.’s RSS Feed Multiple XML Name Spaces
<?xml version="1.0" encoding="UTF-8"?> <rdf:RDF xmlns:rdf=" xmlns=" xmlns:slash=" xmlns:feedburner=" <channel rdf:about=" <title>Slashdot</title> <link> <description>News for nerds, stuff that matters</description> <items> <rdf:Seq> <rdf:li rdf:resource=" /> <rdf:li rdf:resource=" /> </rdf:Seq> </items> <image rdf:resource=" /> <textinput rdf:resource=" /> </channel> <image rdf:about=" <url> </image> <item rdf:about=" <title>Apple's Move May Make AAC Music Industry Standard</title> <link> <description>stivi writes "BusinessWeek has up an article about a war: a standards war...</description> <slash:department>razors-and-razorblades</slash:department> <slash:section>apple</slash:section> <slash:comments>38</slash:comments> <slash:hit_parade>38,36,30,25,4,4,1</slash:hit_parade> <feedburner:origLink> </item> An XML Namespace is a W3C recommendation for providing uniquely named elements and attributes in an XML instance. An XML instance may contain element or attribute names from more than one XML vocabulary. If each vocabulary is given a namespace then the ambiguity between identically named elements or attributes can be resolved. All element names within a namespace must be unique. A simple example would be to consider an XML instance that contained references to a customer and an ordered product. Both the customer element and the product element could have a child element "ID_number". References to the element ID_number would therefore be ambiguous unless the two identically named but semantically different elements were brought under namespaces that would differentiate them. Multiple XML Name Spaces

17 CFMX Built-In XML Functions

18 XML Function Categories
Parsing & Searching Constructing Decision / Logic SOAP Other

19 Parsing & Searching Functions
XmlChildPos Gets the position of a child element within an XML document object. [more info] XmlGetNodeType Determines the type of an XML document object node. [more info] XmlParse Converts XML text into an XML document object. [more info] XmlSearch Uses an XPath language expression to search an XML document object. [more info]

20 XML Construction Functions
XmlFormat Escapes special XML characters in a string so that the string can be used as text in XML. [more info] XmlNew Creates an XML document object. [more info] XmlElemNew Creates an XML document object element. [more info]

21 Decision Functions IsWDDX Determines if a value is a well-formed WDDX packet. [more info] IsXML Determines if a string is well-formed XML text. [more info] IsXmlAttribute Determines whether the function parameter is an XML Document Object Model (DOM) attribute node. [more info] IsXmlDoc Determines whether the function parameter is a ColdFusion XML document object. [more info] IsXmlElem Determines whether the function parameter is an XML document object element. [more info] IsXmlNode Determines whether the function parameter is an XML document object node. [more info] IsXmlRoot Determines whether the function parameter is the root element of an XML document object. [more info]

22 SOAP Functions AddSOAPRequestHeader Adds a SOAP header to a web service request before making the request. [more info] AddSOAPResponseHeader Adds a SOAP response header to a web service response. [more info] GetSOAPRequest Returns an XML object that contains the entire SOAP request. [more info] GetSOAPRequestHeader Obtains a SOAP request header. [more info] GetSOAPResponse Returns an XML object that contains the entire SOAP response after invoking a web service. [more info] GetSOAPResponseHeader Returns a SOAP response header. [more info] IsSOAPRequest Determines whether a CFC is being called as a web service. [more info]

23 Other XML Functions XmlTransform Applies an Extensible Stylesheet Language Transformation (XSLT) to XML. The XML can be in string format or an XML document object. [more info] XmlValidate Uses a Document Type Definition (DTD) or XML Schema to validate an XML text document or an XML document object. [more info]

24 ColdFusion XML Object

25 ColdFusion XML Object <?xml version="1.0" encoding="UTF-8"?>
<recipe name="bread" prep_time="5 mins" cook_time="3 hours"> <title>Basic bread</title> <ingredient amount="3" unit="cups">Flour</ingredient> <ingredient amount="0.25" unit="ounce">Yeast</ingredient> <ingredient amount="1.5" unit="cups" state="warm">Water</ingredient> <ingredient amount="1" unit="teaspoon">Salt</ingredient> <instructions> <step>Mix all ingredients together, and knead thoroughly.</step> <step>Cover with a cloth, and leave for one hour in warm room.</step> <step>Knead again, place in a tin, and then bake in the oven.</step> </instructions> </recipe>

26 ColdFusion XML Object XmlRoot XmlText XmlAttributes XmlChildren
<?xml version="1.0" encoding="UTF-8"?> <recipe name="bread" prep_time="5 mins" cook_time="3 hours"> <title>Basic bread</title> <ingredient amount="3" unit="cups">Flour</ingredient> <ingredient amount="0.25" unit="ounce">Yeast</ingredient> <ingredient amount="1.5" unit="cups" state="warm">Water</ingredient> <ingredient amount="1" unit="teaspoon">Salt</ingredient> <instructions> <step>Mix all ingredients together, and knead thoroughly.</step> <step>Cover with a cloth, and leave for one hour in warm room.</step> <step>Knead again, place in a tin, and then bake in the oven.</step> </instructions> </recipe> XmlRoot XmlText XmlAttributes XmlChildren

27 ColdFusion XML Object XmlRoot Top element. Contains the full XML body / collection of elements. XmlText String value for the current element. XmlAttributes Structure containing all the attribute names and values for the current element. XmlChildren Array containing all the nested (child) elements of the current element.

28 ColdFusion XML Object <?xml version="1.0" encoding="UTF-8"?>
<recipe name="bread" prep_time="5 mins" cook_time="3 hours"> <title>Basic bread</title> <ingredient amount="3" unit="cups">Flour</ingredient> <ingredient amount="0.25" unit="ounce">Yeast</ingredient> <ingredient amount="1.5" unit="cups" state="warm">Water</ingredient> <ingredient amount="1" unit="teaspoon">Salt</ingredient> <instructions> <step>Mix all ingredients together, and knead thoroughly.</step> <step>Cover with a cloth, and leave for one hour in warm room.</step> <step>Knead again, place in a tin, and then bake in the oven.</step> </instructions> </recipe>

29 XmlRoot <?xml version="1.0" encoding="UTF-8"?>
<cfset foo = xmlObj.XmlRoot /> or <cfset foo = xmlObj.recipe /> <?xml version="1.0" encoding="UTF-8"?> <recipe name="bread" prep_time="5 mins" cook_time="3 hours"> <title>Basic bread</title> <ingredient amount="3" unit="cups">Flour</ingredient> <ingredient amount="0.25" unit="ounce">Yeast</ingredient> <ingredient amount="1.5" unit="cups" state="warm">Water</ingr> <ingredient amount="1" unit="teaspoon">Salt</ingredient> <instructions> <step>Mix all ingredients together, and knead thoroughly.</step> <step>Cover with a cloth, and leave for one hour in warm...</step> <step>Knead again, place in a tin, and then bake in the o...</step> </instructions> </recipe>

30 <cfset foo = xmlObj.recipe.title.XmlText />
<?xml version="1.0" encoding="UTF-8"?> <recipe name="bread" prep_time="5 mins" cook_time="3 hours"> <title>Basic bread</title> <ingredient amount="3" unit="cups">Flour</ingredient> <ingredient amount="0.25" unit="ounce">Yeast</ingredient> <ingredient amount="1.5" unit="cups" state="warm">Water</ingredient> <ingredient amount="1" unit="teaspoon">Salt</ingredient> <instructions> <step>Mix all ingredients together, and knead thoroughly.</step> <step>Cover with a cloth, and leave for one hour in warm room.</step> <step>Knead again, place in a tin, and then bake in the oven.</step> </instructions> </recipe>

31 <cfset foo = xmlObj.recipe.ingredient[2].XmlText />
<?xml version="1.0" encoding="UTF-8"?> <recipe name="bread" prep_time="5 mins" cook_time="3 hours"> <title>Basic bread</title> <ingredient amount="3" unit="cups">Flour</ingredient> <ingredient amount="0.25" unit="ounce">Yeast</ingredient> <ingredient amount="1.5" unit="cups" state="warm">Water</ingredient> <ingredient amount="1" unit="teaspoon">Salt</ingredient> <instructions> <step>Mix all ingredients together, and knead thoroughly.</step> <step>Cover with a cloth, and leave for one hour in warm room.</step> <step>Knead again, place in a tin, and then bake in the oven.</step> </instructions> </recipe>

32 <cfset foo = xmlObj.recipe.instructions.step[3].XmlText />
<?xml version="1.0" encoding="UTF-8"?> <recipe name="bread" prep_time="5 mins" cook_time="3 hours"> <title>Basic bread</title> <ingredient amount="3" unit="cups">Flour</ingredient> <ingredient amount="0.25" unit="ounce">Yeast</ingredient> <ingredient amount="1.5" unit="cups" state="warm">Water</ingredient> <ingredient amount="1" unit="teaspoon">Salt</ingredient> <instructions> <step>Mix all ingredients together, and knead thoroughly.</step> <step>Cover with a cloth, and leave for one hour in warm room.</step> <step>Knead again, place in a tin, and then bake in the oven.</step> </instructions> </recipe>

33 XmlAttributes Structure
<cfset foo = xmlObj.recipe.ingredient[2].XmlAttributes /> <?xml version="1.0" encoding="UTF-8"?> <recipe name="bread" prep_time="5 mins" cook_time="3 hours"> <title>Basic bread</title> <ingredient amount="3" unit="cups">Flour</ingredient> <ingredient amount="0.25" unit="ounce">Yeast</ingredient> <ingredient amount="1.5" unit="cups" state="warm">Water</ingredient> <ingredient amount="1" unit="teaspoon">Salt</ingredient> <instructions> <step>Mix all ingredients together, and knead thoroughly.</step> <step>Cover with a cloth, and leave for one hour in warm room.</step> <step>Knead again, place in a tin, and then bake in the oven.</step> </instructions> </recipe>

34 XmlAttributes Key Value
<cfset foo = xmlObj.recipe.ingredient[2].XmlAttributes.unit /> <?xml version="1.0" encoding="UTF-8"?> <recipe name="bread" prep_time="5 mins" cook_time="3 hours"> <title>Basic bread</title> <ingredient amount="3" unit="cups">Flour</ingredient> <ingredient amount="0.25" unit="ounce">Yeast</ingredient> <ingredient amount="1.5" unit="cups" state="warm">Water</ingredient> <ingredient amount="1" unit="teaspoon">Salt</ingredient> <instructions> <step>Mix all ingredients together, and knead thoroughly.</step> <step>Cover with a cloth, and leave for one hour in warm room.</step> <step>Knead again, place in a tin, and then bake in the oven.</step> </instructions> </recipe>

35 <cfset foo = xmlObj.recipe.XmlChildren />
<?xml version="1.0" encoding="UTF-8"?> <recipe name="bread" prep_time="5 mins" cook_time="3 hours"> <title>Basic bread</title> <ingredient amount="3" unit="cups">Flour</ingredient> <ingredient amount="0.25" unit="ounce">Yeast</ingredient> <ingredient amount="1.5" unit="cups" state="warm">Water</ingre> <ingredient amount="1" unit="teaspoon">Salt</ingredient> <instructions> <step>Mix all ingredients together, and knead thoroughly.</step> <step>Cover with a cloth, and leave for one hour in warm r...</step> <step>Knead again, place in a tin, and then bake in the ov...</step> </instructions> </recipe>

36 <cfset foo = xmlObj.recipe.XmlChildren[2] />
<?xml version="1.0" encoding="UTF-8"?> <recipe name="bread" prep_time="5 mins" cook_time="3 hours"> <title>Basic bread</title> <ingredient amount="3" unit="cups">Flour</ingredient> <ingredient amount="0.25" unit="ounce">Yeast</ingredient> <ingredient amount="1.5" unit="cups" state="warm">Water</ingredient> <ingredient amount="1" unit="teaspoon">Salt</ingredient> <instructions> <step>Mix all ingredients together, and knead thoroughly.</step> <step>Cover with a cloth, and leave for one hour in warm room.</step> <step>Knead again, place in a tin, and then bake in the oven.</step> </instructions> </recipe>

37 <cfset foo = xmlObj.recipe.instructions.XmlChildren[1] />
<?xml version="1.0" encoding="UTF-8"?> <recipe name="bread" prep_time="5 mins" cook_time="3 hours"> <title>Basic bread</title> <ingredient amount="3" unit="cups">Flour</ingredient> <ingredient amount="0.25" unit="ounce">Yeast</ingredient> <ingredient amount="1.5" unit="cups" state="warm">Water</ingredient> <ingredient amount="1" unit="teaspoon">Salt</ingredient> <instructions> <step>Mix all ingredients together, and knead thoroughly.</step> <step>Cover with a cloth, and leave for one hour in warm room.</step> <step>Knead again, place in a tin, and then bake in the oven.</step> </instructions> </recipe>

38 Reading & Writing XML to the File System

39 Read in with <CFFILE>
<!--- read in xml file ---> <cffile action="READ" variable="xmlStr" file="#ExpandPath('files/my.xml')#" /> <!--- convert string to xml object ---> <cfset xmlObj = XMLParse(xmlStr) /> <!--- ready to parse! ---> XMLParse = converts the XML string to a collection of Arrays and Structures

40 XML String <CFDUMP>

41 XML Object <CFDUMP>

42 Build XML by Strings <!--- build XML by string --->
<cfxml variable="xmlObj" casesensitive="true"> <conference> <name>CFUNITED</name> <topics>ColdFusion and all that is related.</topics> <dates> <startDate dayOfWeek="Wednesday">June 27th 2007</startDate> <endDate dayOfWeek="Saturday">June 30th 2007</endDate> </dates> <location> <name>Bethesda North Marriott - Montgomery County Conference Center</name> <address>5701 Marinelli Road, North Bethesda, MD 20852</address> </location> </conference> </cfxml>

43 Build XML w/ Functions <cfscript> //Create XML Obj
xmlObj = XmlNew(); //Add all XML Nodes xmlObj.conference = XmlElemNew(xmlObj,"conference"); xmlObj.conference.name = XmlElemNew(xmlObj,"name"); xmlObj.conference.topics = XmlElemNew(xmlObj,"topics"); xmlObj.conference.dates = XmlElemNew(xmlObj,"dates"); xmlObj.conference.dates.startDate = XmlElemNew(xmlObj,"startDate"); xmlObj.conference.dates.endDate = XmlElemNew(xmlObj,"endDate"); xmlObj.conference.location = XmlElemNew(xmlObj,"location"); xmlObj.conference.location.name = XmlElemNew(xmlObj,"name"); xmlObj.conference.location.address = XmlElemNew(xmlObj,"address"); //Set XML Text Values xmlObj.conference.name.XmlText = "CFUNITED"; xmlObj.conference.topics.XmlText = "ColdFusion and all that is related."; xmlObj.conference.dates.startDate.XmlText = "June 27th 2007"; xmlObj.conference.dates.endDate.XmlText = "June 30th 2007"; xmlObj.conference.location.name.XmlText = "Bethesda North Marriott - Montgomery County Conference Center"; xmlObj.conference.location.address.XmlText = "5701 Marinelli Road, North Bethesda, MD 20852"; //Set XML Attributes StructInsert(xmlObj.conference.dates.startDate.XmlAttributes,"dayOfWeek","Wednesday",true); StructInsert(xmlObj.conference.dates.endDate.XmlAttributes,"dayOfWeek","Saturday",true); </cfscript>

44 <CFDUMP> the same

45 Write with <CFFILE>
<!--- save xml to file ---> <cffile action="WRITE" output="#xmlObj#" file="#ExpandPath('files/my.xml')#" />

46 XML From Web Services

47 Flickr REST Web Service
<!--- connect to flickr api ---> <cfhttp url=" method="GET"> <cfhttpparam type="url" name="api_key" value="[YOUR_FLICKr_API_KEY]" /> <cfhttpparam type="url" name="method" value="flickr.photos.getRecent" /> <cfhttpparam type="url" name="per_page" value="10" /> </cfhttp> <!--- convert xml string to xml object ---> <cfset flickrXml = XmlParse(CFHTTP.FileContent) /> <!--- <cfdump var="#flickrXml#" label="flickrXml" /> ---> <!--- loop over and display results ---> <cfoutput> <cfloop index="ii" from="1" to="#ArrayLen(flickrXml.rsp.photos.photo)#"> <cfset thisFoto = flickrXml.rsp.photos.photo[ii].XmlAttributes /> <img src=" /><br /> </cfloop> </cfoutput>

48 Flickr REST Web Service
<!--- connect to flickr api ---> <cfhttp url=" method="GET"> <cfhttpparam type="url" name="api_key" value="[YOUR_FLICKr_API_KEY]" /> <cfhttpparam type="url" name="method" value="flickr.photos.getRecent" /> <cfhttpparam type="url" name="per_page" value="10" /> </cfhttp> <!--- convert xml string to xml object ---> <cfset flickrXml = XmlParse(CFHTTP.FileContent) /> <!--- <cfdump var="#flickrXml#" label="flickrXml" /> ---> <!--- loop over and display results ---> <cfoutput> <cfloop index="ii" from="1" to="#ArrayLen(flickrXml.rsp.photos.photo)#"> <cfset thisFoto = flickrXml.rsp.photos.photo[ii].XmlAttributes /> <img src=" /><br /> </cfloop> </cfoutput>

49 SOAP Request & Response
SOAP Request:<soap:Envelope xmlns:soap=" <soap:Body> <getProductDetails xmlns=" <productID>827635</productID> </getProductDetails> </soap:Body></soap:Envelope>SOAP Response:<soap:Envelope xmlns:soap=" <soap:Body> <getProductDetailsResponse xmlns=" <getProductDetailsResult> <productName>Toptimate 3-Piece Set</productName> <productID>827635</productID> <description>3-Piece luggage set. Black Polyester.</description> <price currency="NIS">96.50</price> <inStock>true</inStock> </getProductDetailsResult> </getProductDetailsResponse> </soap:Body></soap:Envelope>

50 Stock Symbol SOAP Web Service
<cfscript> sym = "GOOG"; ws = CreateObject("webservice"," ws.getQuote(sym); wsResponse = getSoapResponse(ws); stockInfo = wsResponse["soap:Envelope"]["soap:Body"]["GetQuoteResponse"]["GetQuoteResult"] ["StockQuote"]; coName = stockInfo["Company"].XmlText; price = stockInfo["Price"].XmlText; </cfscript> <cfoutput> Company: #coName#<br/> Stock Symbol: #sym#<br/> Price: #DollarFormat(ReReplace(price,"[^0-9.]","","ALL"))# </cfoutput> <!--- <cfdump var="#wsResponse#" label="wsResponse" /> --->

51 Stock Symbol SOAP Web Service
<cfscript> sym = "GOOG"; ws = CreateObject("webservice"," ws.getQuote(sym); wsResponse = getSoapResponse(ws); stockInfo = wsResponse["soap:Envelope"]["soap:Body"]["GetQuoteResponse"]["GetQuoteResult"] ["StockQuote"]; coName = stockInfo["Company"].XmlText; price = stockInfo["Price"].XmlText; </cfscript> <cfoutput> Company: #coName#<br/> Stock Symbol: #sym#<br/> Price: #DollarFormat(ReReplace(price,"[^0-9.]","","ALL"))# </cfoutput> <!--- <cfdump var="#wsResponse#" label="wsResponse" /> --->

52 Common XML Tasks

53 XPath Search with XmlSearch
<!--- read in xml file ---> <cffile action="READ" file="#ExpandPath('files/library.xml')#" variable="xmlStr" /> <!--- convert from string to xml object ---> <cfset xmlObj = XMLParse(xmlStr) /> <!--- return matching array from xpath search ---> <cfset xmlSrch = XmlSearch(xmlObj, "/library/author/name") /> <!--- dump the matching results ---> <cfdump var="#xmlObj#" label="xmlObj" />

54 Convert XML to Query <!--- read in xml file --->
<cffile action="READ" file="#ExpandPath('files/library.xml')#" variable="xmlStr" /> <!--- convert from string to xml object ---> <cfset xmlObj = XMLParse(xmlStr) /> <!--- return matching array from xpath search ---> <cfset xmlSrch = XmlSearch(xmlObj, "/library/author/name") /> <!--- dump the matching results ---> <cfdump var="#xmlObj#" label="xmlObj" />

55 Convert Query to XML <!--- create a query object and fill it with data ---> <cfscript> qryObj = QueryNew("descr, pop", "varchar,decimal");QueryAddRow(qryObj, 6); QuerySetCell(qryObj, "descr", "Africa", 1); QuerySetCell(qryObj, "pop", , 1); QuerySetCell(qryObj, "descr", "Asia", 2); QuerySetCell(qryObj, "pop", , 2); QuerySetCell(qryObj, "descr", "Europe", 3); QuerySetCell(qryObj, "pop", , 3); QuerySetCell(qryObj, "descr", "Central & South America", 4); QuerySetCell(qryObj, "pop", , 4); QuerySetCell(qryObj, "descr", "North America", 5); QuerySetCell(qryObj, "pop", , 5); QuerySetCell(qryObj, "descr", "Oceania", 6); QuerySetCell(qryObj, "pop", , 6); </cfscript> <!--- create an xml object and fill with query output ---> <cfxml variable="xmlObj" casesensitive="true"> <Stats year="2005" src=" <cfoutput query="qryObj"> <Continent> <Descr>#XmlFormat(descr)#</Descr> <Population>#pop#</Population> </Continent> </cfoutput> </Stats> </cfxml> <!--- save xml to file ---> <cffile action="WRITE" output="#xmlObj#" file="#ExpandPath('files/world_pop.xml')#" />

56 Convert Query to XML <!--- create a query object and fill it with data ---> <cfscript> qryObj = QueryNew("descr, pop", "varchar,decimal");QueryAddRow(qryObj, 6); QuerySetCell(qryObj, "descr", "Africa", 1); QuerySetCell(qryObj, "pop", , 1); QuerySetCell(qryObj, "descr", "Asia", 2); QuerySetCell(qryObj, "pop", , 2); QuerySetCell(qryObj, "descr", "Europe", 3); QuerySetCell(qryObj, "pop", , 3); QuerySetCell(qryObj, "descr", "Central & South America", 4); QuerySetCell(qryObj, "pop", , 4); QuerySetCell(qryObj, "descr", "North America", 5); QuerySetCell(qryObj, "pop", , 5); QuerySetCell(qryObj, "descr", "Oceania", 6); QuerySetCell(qryObj, "pop", , 6); </cfscript> <!--- create an xml object and fill with query output ---> <cfxml variable="xmlObj" casesensitive="true"> <Stats year="2005" src=" <cfoutput query="qryObj"> <Continent> <Descr>#XmlFormat(descr)#</Descr> <Population>#pop#</Population> </Continent> </cfoutput> </Stats> </cfxml> <!--- save xml to file ---> <cffile action="WRITE" output="#xmlObj#" file="#ExpandPath('files/world_pop.xml')#" />

57 Convert XML to Query <!--- read in xml file --->
<cffile action="READ" file="#ExpandPath('files/ipod_sales.xml')#" variable="xmlStr" /> <!--- convert from string to xml object ---> <cfset xmlObj = XMLParse(xmlStr) /> <!--- create a query object and fill with the xml data ---> <cfset qryObj = QueryNew("salesPeriod, qty", "varchar,decimal") /> <cfloop index="ii" from="1" to="#ArrayLen(xmlObj.sales.period)#"> <cfset temp = QueryAddRow(qryObj, 1) /> <cfset temp = QuerySetCell(qryObj, "salesPeriod", #xmlObj.sales.period[ii].descr.XmlText#) /> <cfset temp = QuerySetCell(qryObj, "qty", #xmlObj.sales.period[ii].qty.XmlText#) /> </cfloop> <!--- dump the query and xml objects ---> <cfdump var="#qryObj#" label="qryObj" /> <cfdump var="#xmlObj#" label="xmlObj" />

58 Convert XML to Query <!--- read in xml file --->
<cffile action="READ" file="#ExpandPath('files/ipod_sales.xml')#" variable="xmlStr" /> <!--- convert from string to xml object ---> <cfset xmlObj = XMLParse(xmlStr) /> <!--- create a query object and fill with the xml data ---> <cfset qryObj = QueryNew("salesPeriod, qty", "varchar,decimal") /> <cfloop index="ii" from="1" to="#ArrayLen(xmlObj.sales.period)#"> <cfset temp = QueryAddRow(qryObj, 1) /> <cfset temp = QuerySetCell(qryObj, "salesPeriod", #xmlObj.sales.period[ii].descr.XmlText#) /> <cfset temp = QuerySetCell(qryObj, "qty", #xmlObj.sales.period[ii].qty.XmlText#) /> </cfloop> <!--- dump the query and xml objects ---> <cfdump var="#qryObj#" label="qryObj" /> <cfdump var="#xmlObj#" label="xmlObj" />

59 Get Child Node Names <cfscript>
//this udf will return a structure with child info on passed xml element function childInfo(xmlElem) { var result = StructNew(); var ii = 0; result.childNameList = ""; result.childCnt = ArrayLen(xmlElem.XmlChildren); if(result.childCnt GT 0) { for(ii = 1; ii LTE result.childCnt; ii = ii + 1) result.childNameList = ListAppend(result.childNameList, xmlElem.XmlChildren[ii].XmlName); } return result; </cfscript> <!--- read in xml file and convert it to xml object ---> <cffile action="READ" file="#ExpandPath('files/songs.xml')#" variable="xmlStr" /><cfset xmlObj = XMLParse(xmlStr) /> <!--- pick xml element to examine and call udf ---> <cfset myXmlElemStr = "xmlObj.library.songs.song[2]" /> <cfset myXmlElem = Evaluate(myXmlElemStr) /><cfset myXmlElemInfo = childInfo(myXmlElem) /> <!--- output xml element name and child info ---> <cfoutput> #myXmlElemStr# has #myXmlElemInfo.childCnt# child<cfif myXmlElemInfo.childCnt NEQ 1>ren</cfif> <cfif myXmlElemInfo.childCnt GT 0>(#myXmlElemInfo.childNameList#)</cfif> </cfoutput>

60 Get Child Node Names <cfscript>
//this udf will return a structure with child info on passed xml element function childInfo(xmlElem) { var result = StructNew(); var ii = 0; result.childNameList = ""; result.childCnt = ArrayLen(xmlElem.XmlChildren); if(result.childCnt GT 0) { for(ii = 1; ii LTE result.childCnt; ii = ii + 1) result.childNameList = ListAppend(result.childNameList, xmlElem.XmlChildren[ii].XmlName); } return result; </cfscript> <!--- read in xml file and convert it to xml object ---> <cffile action="READ" file="#ExpandPath('files/songs.xml')#" variable="xmlStr" /><cfset xmlObj = XMLParse(xmlStr) /> <!--- pick xml element to examine and call udf ---> <cfset myXmlElemStr = "xmlObj.library.songs.song[2]" /> <cfset myXmlElem = Evaluate(myXmlElemStr) /><cfset myXmlElemInfo = childInfo(myXmlElem) /> <!--- output xml element name and child info ---> <cfoutput> #myXmlElemStr# has #myXmlElemInfo.childCnt# child<cfif myXmlElemInfo.childCnt NEQ 1>ren</cfif> <cfif myXmlElemInfo.childCnt GT 0>(#myXmlElemInfo.childNameList#)</cfif> </cfoutput>

61 Dynamically Drill XML <cfscript>
//this udf is recursive, it will return all info for the passed element, and it's family tree on downward function drillXml(xmlElem) { var ii = 0; var name = xmlElem.XmlName; var childCnt = ArrayLen(xmlElem.XmlChildren); WriteOutput("<ul>"); if(childCnt EQ 1) WriteOutput("<li>" & name & " has " & childCnt & " child</il>"); else WriteOutput("<li>" & name & " has " & childCnt & " children</il>"); if(childCnt GT 0) { for(ii = 1;ii LTE childCnt;ii = ii + 1) drillXml(xmlElem.XmlChildren[ii]); } WriteOutput("</ul>"); </cfscript> <!--- read in xml file and convert string to xml object ---> <cffile action="READ" file="#ExpandPath('files/songs.xml')#" variable="xmlStr" /> <cfset xmlObj = XMLParse(xmlStr) /> <!--- call udf that will display drill-down output ---> <cfoutput>#drillXml(xmlObj.xmlRoot)#</cfoutput>

62 Dynamically Drill XML <cfscript>
//this udf is recursive, it will return all info for the passed element, and it's family tree on downward function drillXml(xmlElem) { var ii = 0; var name = xmlElem.XmlName; var childCnt = ArrayLen(xmlElem.XmlChildren); WriteOutput("<ul>"); if(childCnt EQ 1) WriteOutput("<li>" & name & " has " & childCnt & " child</il>"); else WriteOutput("<li>" & name & " has " & childCnt & " children</il>"); if(childCnt GT 0) { for(ii = 1;ii LTE childCnt;ii = ii + 1) drillXml(xmlElem.XmlChildren[ii]); } WriteOutput("</ul>"); </cfscript> <!--- read in xml file and convert string to xml object ---> <cffile action="READ" file="#ExpandPath('files/songs.xml')#" variable="xmlStr" /> <cfset xmlObj = XMLParse(xmlStr) /> <!--- call udf that will display drill output ---> <cfoutput>#drillXml(xmlObj.library)#</cfoutput>

63 XML as a Data Storage

64 Benefits of XML Storage
No ColdFusion Data Source to configure No Database Server required Move XML storage file(s) with CFML files Easily convert XML data to Query object if query functionality is needed

65 Downsides of XML Storage
Does not offer locking / data collision protection of a real Database Server Not scalable not suited for large amounts of data Parsing XML data puts even more load on ColdFusion, normally handled by the DB Lack of full SQL commands offered by DBs

66 Tips UUID() everything, must be able to uniquely reference each node
Break data up into segmented chunks (where it makes sense)

67 Let’s look at working application and code...
Tips UUID() everything, must be able to uniquely reference each node Break data up into segmented chunks (where it makes sense) Let’s look at working application and code...

68 On-line Resources Documentation & Examples
CFQuickDocs - Adobe LiveDocs - Community CFLib.org - Andrew Schwabe - Software XPath Explorer -

69 Q & A Thank You Erik Goodlad www.errorik.com egoodlad@gmail.com
June 27th - 30th 2007 69


Download ppt "How to: Read, Write, and Use XML in CFMX"

Similar presentations


Ads by Google