If you had some curiosity why it would keep all the formatting, the answer is in the XmlText attribute of the object itself. Anything between the beginning and ending of the tag that is not contained in other tags is included in the tag's text, which by default includes all XML formatting.
Using the cfxml tag is much more friendly and efficient, in general, than using cfscript. However, when the client wants the XML to use as little bandwidth as necessary, how do you get around that?
In order to have the tag compressed, I've developed an XML compression function. It will take any XML object as a parameter, and rebuilds it with script. Doing this, it strips out all the formatting between the tags by testing the XmlText. If that XmlText, when trimmed, provides no information, it is not valid text and is removed from that tag. This effectively removes any white space that was used in formatting, while preserving spacing between words in text for children.
The functions I developed to do this are included below, should you wish to use them. These functions are written in cfscript and must be contained in a cfscript block according.
Note: In ColdFusion 8, all cfscript functions declared in a CFC are public. The function declaration ise done with cffunction, then the body contained in script, to prevent web service users from calling it directly.
The functions are included below. In the event that they are being placed in a CFC to be used internally by ColdFusion apps, the first function can be set to access public. The second function, used only for recursion, should never be made public.
<cffunction access="private" name="XMLCompress" returntype="xml">
<cfargument name="sourceXML" type="xml" required="yes">
<cfscript>
var toReturn = xmlNew(false);
var newRoot = XMLTagCompress(toReturn, sourceXML.XmlRoot);
toReturn.xmlRoot = xmlElemNew(toReturn, sourceXML.xmlRoot.XmlName);
for (child = 1; child LTE ArrayLen(sourceXML.xmlRoot.XmlChildren); child ++) {
toReturn.xmlRoot.XmlChildren[child] = XmlTagCompress(toReturn, sourceXML.xmlRoot.XmlChildren[child]);
}
return toReturn;
</cfscript>
</cffunction>
<cffunction access="private" name="XMLTagCompress" returntype="xml">
<cfargument name="sourceXML" type="xml" required="yes">
<cfargument name="xmlElement" type="xml" required="yes">
<cfscript>
var currentChild = 1;
var compressedNode = xmlElemNew(sourceXML, xmlElement.XmlName);
if (Len(Trim(xmlElement.XmlText)) GT 0)
compressedNode.XmlText = xmlElement.XmlText;
for (attrib in xmlElement.XmlAttributes) {
compressedNode.XmlAttributes[attrib] = xmlElement.XmlAttributes[attrib];
}
while (currentChild LTE ArrayLen(xmlElement.XmlChildren)) {
compressedNode.XmlChildren[currentChild] = XMLTagCompress(sourceXML, xmlElement.XmlChildren[currentChild]);
currentChild ++;
}
return compressedNode;
</cfscript>
</cffunction>
With these functions, I was able to rewrite yesterday's Coldfusion web service to appear as shown below:
<cffunction name="getOSInfo"
access="remote"
output="yes">
<cfargument name="os_or"
type="numeric"
required="no"
default="0">
<cfcontent type="application/xml" reset="yes">
<cfquery name="getOS" datasource="[[removed for security]]">
[[ removed for security ]]
</cfquery>
<!--- Tag XML does not reduce white space--->
<cfxml variable="xmlValue">
<oslist>
<cfloop query="getOS">
<os id="#getOS.id#">
<brand>#XMLFormat(getOS.brand)#</brand>
<family>#XMLFormat(getOS.family)#</family>
<type>#XMLFormat(getOS.type)#</type>
<name>#XMLFormat(getOS.name)#</name>
</os>
</cfloop>
</oslist>
</cfxml>
<!--- By running the custom XMLCompress function
the data is returned with formatting removed --->
#XMLCompress(xmlValue)#
<cfabort>
</cffunction>