indentXml(xml [, indent])
Last updated July 30, 2010
Version: 2 | Requires: ColdFusion 8 | Library: CFMLLib
Description:
XML and other markup is much easier to visually scan when the indentation is carefully balanced. This UDF will reformat markup into properly indented lines. Unlike most XML pretty-printers, however, it doesn't NOT use XSLT, just simple string manipulation. This allows it to format pretty much any XML-like markup, well-formed or not. Non-well-formed markup might not be perfectly indented (e.g. a non-closed BR tag will offset following tags by one stop), but it will at least be indented in a useful fashion.
Return Values:
Returns a string.
Example:
Parameters:
| Name | Description | Required |
|---|---|---|
| xml | XML string to format. | Yes |
| indent | String used for creating the indention. Defaults to a space. | No |
Full UDF Source:
<!---
indentXml pretty-prints XML and XML-like markup without requiring valid XML.
@param xml XML string to format. (Required)
@param indent String used for creating the indention. Defaults to a space. (Optional)
@return Returns a string.
@author Barney Boisvert (bboisvert@gmail.com)
@version 2, July 30, 2010
--->
<cffunction name="indentXml" output="false" returntype="string">
<cfargument name="xml" type="string" required="true" />
<cfargument name="indent" type="string" default=" "
hint="The string to use for indenting (default is two spaces)." />
<cfset var lines = "" />
<cfset var depth = "" />
<cfset var line = "" />
<cfset var isCDATAStart = "" />
<cfset var isCDATAEnd = "" />
<cfset var isEndTag = "" />
<cfset var isSelfClose = "" />
<cfset xml = trim(REReplace(xml, "(^|>)\s*(<|$)", "\1#chr(10)#\2", "all")) />
<cfset lines = listToArray(xml, chr(10)) />
<cfset depth = 0 />
<cfloop from="1" to="#arrayLen(lines)#" index="i">
<cfset line = trim(lines[i]) />
<cfset isCDATAStart = left(line, 9) EQ "<![CDATA[" />
<cfset isCDATAEnd = right(line, 3) EQ "]]>" />
<cfif NOT isCDATAStart AND NOT isCDATAEnd AND left(line, 1) EQ "<" AND right(line, 1) EQ ">">
<cfset isEndTag = left(line, 2) EQ "</" />
<cfset isSelfClose = right(line, 2) EQ "/>" OR REFindNoCase("<([a-z0-9_-]*).*</\1>", line) />
<cfif isEndTag>
<!--- use max for safety against multi-line open tags --->
<cfset depth = max(0, depth - 1) />
</cfif>
<cfset lines[i] = repeatString(indent, depth) & line />
<cfif NOT isEndTag AND NOT isSelfClose>
<cfset depth = depth + 1 />
</cfif>
<cfelseif isCDATAStart>
<!---
we don't indent CDATA ends, because that would change the
content of the CDATA, which isn't desirable
--->
<cfset lines[i] = repeatString(indent, depth) & line />
</cfif>
</cfloop>
<cfreturn arrayToList(lines, chr(10)) />
</cffunction>
Search CFLib.org
Latest Additions
Shawn Porter added
DeMoronize
3 hour(s) ago
Chris Carey added
readPropertiesFi...
1 day(s) ago
Randy Johnson added
lastDayofWeek
3 day(s) ago
Frank Marion added
sitemapPing
7 day(s) ago
Top Rated
QuickSort
Rated 5.0, 3 time(s)
indentXml
Rated 5.0, 3 time(s)
queryColumnsToSt...
Rated 5.0, 3 time(s)
generateSsccAsn
Rated 5.0, 3 time(s)