#Working with XML in ColdFusion
Cheatsheet with code examples to read, create and search xml files
ColdFusion provides many built-in functions for doing all sort of XML based operations.
###Reading XML Document Read the document then passes it to the parser to create an XML object
<cffile action="read" file="#ExpandPath('./some.xml')#" variable="myXML" />
<cfset myDoc=XmlParse(myXML) />
The XmlParse can also read the file so we can avoid one step here.
<cfset myDoc=XmlParse(ExpandPath("./some.xml")) />
###Generating an XML with data from a database
<!--- Get some data from the database --->
<cfquery name="getData" datasource="ts24.travel">
SELECT * FROM TestData
</cfquery>
<!--- Create the XML with the getData var --->
<cfxml variable="testXML">
<cfoutput query="getData">
<id>#getData.id#</id>
<myDataAlfa>#getData.myDataAlfa#</myDataAlfa>
<myDataAlfa>#getData.myDataAlfa#</myDataAlfa>
<myDataInt>#getData.myDataInt#</myDataInt>
</cfoutput>
</cfxml>
<!--- Write the XML out in a document --->
<cffile action="write" file="#ExpandPath('./out.xml')#" output="#testXML#" />
<!--- Dump Output to the Browser --->
<cfdump var="#testXML#" />
###Parsing XML Coldfusion has one function to parse xml files. This function has a casesensitive property that can be enabled or disabled when reading the XML file. xmlParse can read xml documents from a local file, URL or a string containing XML code. It can also validate XML based on a DTD or schema.
In this example I'm reading a local file
<cfset myDoc=xmlParse("./testXML.xml", [true || false (default is false)]*)
xmlParse takes 2 arguments, the path where the file is located and casesensitive true or false.
The XML file looks like this:
<testXML>
<art>
<itemName Type="1">Art Name</item>
</art>
</testXML>
We can access to the root of the document as follow if the case sensitive is false:
myDoc.testxml
if the case sensitive is true, this will produce an error. The right way to do it would be like this:
myDoc.xmlRoot
The same is also true with nodes and attributes
case sensitive false:
myDoc.testXML.art[1].itemname.xmltext
case sensitive true:
myDoc.xmlRoot.xmlChildren[1]["itemName"]
###XML to String
<cfset xmlString=toString(myDoc) />
###Looping over XML Knowing the structure of the document
<cfloop array="#myDoc.testxml.art.xmlchildren#" index="i">
<cfoutput>
name: #i.itemName.xmlText#<br/>
</cfoutput>
<br/>
</cfloop>
###Setting XML Node Value
<cfloop array="#myDoc.testXML.art.xmlchildren#" index="i">
<!--- set a new name --->
<cfset i.itemName.xmlText = "Jonny" />
</cfloop>
###Convert XML to Query Result Set
<cfscript>
artQuery = QueryNew("artistid, artid, name, description, image, price, sold");
queryAddRow(artQuery, arraylen(myDoc.art.piece));
for (i = 1; i lte arraylen(myDoc.art.piece); i++){
thisItem = mydoc.art.piece[i];
QuerySetCell(artQuery, "artistid", mydoc.art.xmlAttributes.artistid, i);
QuerySetCell(artQuery, "artid", thisItem.xmlAttributes.id, i);
QuerySetCell(artQuery, "sold", thisItem.xmlAttributes.available, i);
QuerySetCell(artQuery, "name", thisItem.artname.xmltext, i);
QuerySetCell(artQuery, "description", thisItem.description.xmltext, i);
QuerySetCell(artQuery, "image", thisItem.image.xmltext, i);
QuerySetCell(artQuery, "price", thisItem.price.xmltext, i);
}
writedump(artQuery);
</cfscript>
###Searching XML
<cffile action="read" file"#ExpandPath('./out.xml')#" variable="myXML" />
<cfset myDoc=XmlParse(myXML) />
<cfscript>
params = structNew();
params["artname"] = "Mary";
</cfscript>
<cfset searchRes=xmlSearch(myXML, '//piece/artname[. = $artname], params) />
<cfdump var="#searchRes[1].xmlParent#" />