CFLib.org – Common Function Library Project

indentXml(xml [, indent])

Last updated July 30, 2010
Download UDF

author

Barney Boisvert Barney Boisvert

Version: 2 | Requires: ColdFusion 8 | Library: CFMLLib

 
Rated 3 time(s). Average Rating: 5.0

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:

<pre>#htmlEditFormat(indentXml('<html><head><title>Test Page</title></head><body><h1>Hello!</h1></body></html>'))#</pre>

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 Shawn Porter added
DeMoronize
3 hour(s) ago

Chris Carey Chris Carey added
readPropertiesFi...
1 day(s) ago

Randy Johnson Randy Johnson added
lastDayofWeek
3 day(s) ago

Frank Marion Frank Marion added
sitemapPing
7 day(s) ago

Top Rated

James Sleeman                                     QuickSort
Rated 5.0, 3 time(s)

Barney Boisvert indentXml
Rated 5.0, 3 time(s)

Nathan Dintenfass                                 queryColumnsToSt...
Rated 5.0, 3 time(s)

Kevin Pepperman generateSsccAsn
Rated 5.0, 3 time(s)

Created by Raymond Camden / Design by Justin Johnson