Archive for the 'code' Category

Problem with WordPress messing up HTML with P and BR tags.

Saturday, August 18th, 2007

Maybe you don’t want to disable wpautop but you are sick of WordPress adding <p> and <br /> tags to your included html.

A solution is to open up wp-includes/formatting-functions.php and modify the wpautop function. In this version, you can make wpautop respect any tags you want. Just add them!

Usage

Simply add your tag name inside the variable below, using the same tag-pip-tag format:

//WP Version 2.0.4
function wpautop($pee, $br = 1) {
        $allowedTags = 'table|thead|tfoot|caption|colgroup|tbody|tr|td|th|div|dl|dd|dt|ul|ol|li|pre| select|fieldset|legend|form|blockquote|address|math|p|h[1-6]';
        $allowedCloseTags = 'option|select|p|li|div|dl|dd|dt|th|pre|td|ul|ol';

//WP Version 2.2.3
function wpautop($pee, $br = 1) {
        $pee = $pee . "\\n"; // just to make things a little easier, pad the end
        $pee = preg_replace('|\\s*|’, “\\n\\n”, $pee);
        // Space things out a little
        $allblocks = ‘(?:table|thead|tfoot|caption|colgroup|tbody|tr|td|th|div|dl|dd|dt|ul|ol|li|pre|select|form|map|area|blockquote|address|math|style|input|p|h[1-6]|hr)’;

ATTENTION

If you mess up WordPress and can’t get anything to work, you should have made a backup! Sorry!

Relevant links

WordPress Forums: How do I remove <p> from the_content ?
WordPress Forums: Hey Wordpress STOP Screwing up my HTML in my posts!

ASP Function RStoCSV - Converts a RecordSet to Excel

Thursday, August 9th, 2007

Usage

call RStoCSV(recordSetObject,"MyFileName")

Note

Requires yStr

yourFunctionsFile.asp

function RStoCSV(rs, filename)
	set output = new yStr
	total = rs.Fields.Count
	count = 0
	for each x in rs.Fields
		output.App """" & x.name & """"
		if count < total then
			output.App ","
		end if
		count = count + 1
	next
	output.App vbCrLf
	While not rs.EOF
		set record = new yStr
		for each x in rs.fields
			if(isNull(x)) or x = "" then
				x = " "
			end if
			'x = Replace(x,",","\\,")
			if record.output = "" then
				record.App """" & x
			else
				record.App """,""" & x
			end if
		next
		output.App record.output & """" & vbCrLf
		rs.movenext
	wend
	Response.Clear()
	Set userAgent=Server.CreateObject("MSWC.BrowserType")
	if userAgent.browser = "IE" then
		Response.AddHeader "Content-Disposition","attachment;filename=export.csv"
		Response.ContentType = "text/csv"
	else
		Response.AddHeader "Content-Disposition","attachment;filename=" & Replace(filename," ","_") &".csv"
		response.ContentType = "text/csv"
	end if
	response.write output.output
	response.End
end function

rr - the best, shortest, sweetest ASP subroutine which replaces response.write

Tuesday, July 31st, 2007

Typing out Response.Write a million times per project is so annoying. Do this instead.

Usage:

     rr "Choo choo!!"

yourFunctions.asp

sub rr(input)
     response.write input
end sub

yStr - an ASP Class for concatenating / appending strings.

Saturday, July 21st, 2007

This is a handy-dandy feature that replaces variable = variable & "stuffToAppend". Dear god that gets old quick.

Anyway, its not mine. I found it somewhere a long time ago on the internet and now I can’t find the link to give them credit. Oh yeah, it was here. Dear god, he takes 10 paragraphs to explain the function below and why you should use it. I will do it in one line:

If you use the x = x & “blah” method, you’re a dope with ugly code. =)

Usage


SQL = new yStr
SQL.Append “SELECT * FROM”
SQL.Append ” myTable ”
SQL.App      “WHERE 1″   ‘.App is same as .Append but … shorter. =)

SQL.output() ‘#outputs SELECT * FROM myTable WHERE 1

SQL.reset     ‘# … uhm. Resets it so it doesn’t equal anything anymore.

yourClassFile.asp

Class yStr
	Dim stringArray,growthRate,numItems
	Private Sub Class_Initialize()
		growthRate = 50: numItems = 0
		ReDim stringArray(growthRate)
	End Sub
	Public Sub App(ByVal strValue)
		Append(strValue)
	end Sub
	Public Sub Append(ByVal strValue)
		strValue=strValue & "" ' prevents type mismatch error if strValue is null. Performance hit is negligible.
		If numItems > UBound(stringArray) Then ReDim Preserve stringArray(UBound(stringArray) + growthRate)
		stringArray(numItems) = strValue:numItems = numItems + 1
	End Sub
	Public Sub Reset
		Erase stringArray
		Class_Initialize
	End Sub
	Public Function output()
		Redim Preserve stringArray(numItems)
		output = Join(stringArray, "")
	End Function
End Class

ASP on Rails tutorial | Part 2: Updating

Friday, July 20th, 2007

Picking up from part 1: adding

Let’s say your users saved their info and viewAccount.asp prefills this form:




/
/

Let’s say they change their birthDate to ‘4/15/2007′, the Query String looks like:

id=123 & firstName=Marilyn & lastName=Manson & birthMM=4 & birthDD=15 & birthYYYY=2007 & likeWhiskey=yes

Again, your database table “users” looks like:

firstName (VARCHAR), lastName (VARCHAR), birthDate (DATETIME), likeWhiskey(BIT)

To updated the record, just do the following:

< %
set myUser = new ySQL

myUser.Table("users")					'Select table . . .

if myUser.Update(   Session("userID")   ) = true then
    response.write "Changes made!"
else
    response.write "No changes made!"
end if
Response.Redirect "viewProfile.asp?id=" & newUserID ' . . . Send them on their way!
%>

The Update() method knows to loop through POST or GET variables and compare them with fields in the existing record. Each time it finds a difference the method updates the field accordingly.

Download

Next week: Deleting, Combining, outputting to XML, and other handy tricks

ASP on Rails tutorial | Part 1: Adding

Friday, July 20th, 2007

Creating a flexible script-to-database go-between in ASP?! You’ve got to be kidding!

For those of us stuck maintaining legacy ASP, here’s a handy way to add, update, and delete records from a database.
Let’s say your users submit their info to addAccount.asp GET or POST with this form:




/
/

When submitted, the Query String looks like:

firstName=Marilyn & lastName=Manson & birthMM=4 & birthDD=15 & birthYYYY=2007 & likeWhiskey=yes

And your database table “users” looks like:

firstName (VARCHAR), lastName (VARCHAR), birthDate (DATETIME), likeWhiskey(BIT)

Would you believe me if I said the following script could add the record to the database?

addAccount.asp

< %@LANGUAGE="VBSCRIPT"%>

< %
set myUser = new ySQL  myUser.Table("users")	     'Select table . . .
newUserID = myUser.Add()					' . . . Add submitted info to table . . .
Response.Redirect "viewProfile.asp?id=" & newUserID	' . . . Send them on their way!
%>

…that’s it! The Add() method “knows” all. It knows to match the form and database fields, even if those fields are broken up dates or if the database field is a bit 1 or 0, true or false. It cleans the SQL of ugly characters and SQL injection attempts.

You probably have some questions at this point.

“B-b-but I can’t trust my users! What if I have a field like “userLevel” which I don’t want users to be able to mess with?”

Easy. Just call myTable.exclude("userLevel").

“What if I want to collect their address too, but I want to store it in another table and I want to link the “users” table to the “addresses” table when I add?”

newUserID = myUser.Add()

myAddy = new ySQL
myAddy.Table("user_addresses")
myAddy.exception "userID",newUserID	'Need an exception, since "userID" wasn't passed by form.
addressID = myAddy.Add()			'Address is added with the correct userID

“But what if I have many items to store like table: user_interests (userID, interest, rating)?”




. . .infinity

Easy. Just call AddMany() instead of Add(). It knows to loop through the QueryString and match up the correct interest and rating. Make sure to set myInterest.exception "userID", newUserID first!

Download

Next: Updating existing records!

ySQL

Sunday, July 1st, 2007

Requires yStr


< %
<%
'#############
'#
'#	ASP on Rails version 1.0
'#	Questions? stephen@yeago.net
'#	...Yes, I know the name is cheesy.
'#
'#############
Class ySQL
	Private i_id
	Private i_Table		'# "i_" = "internal"
	Private i_TableRS
	Private i_TableArray
	Private i_Exclusions
	Private i_Exceptions
	Private i_Dependz	'# Not the Adult diaper
	Private i_debugMode
	Private Conn
	Private Sub Class_Initialize
		set i_Exclusions = Server.CreateObject("Scripting.Dictionary")
		set i_Exceptions = Server.CreateObject("Scripting.Dictionary")
		set i_Dependz = Server.CreateObject("Scripting.Dictionary")
		exclude("id")
		set Conn = CreateObject("ADODB.Connection")
		'DSNtest="DRIVER={SQL Server};SERVER=???;UID=???;PWD=???;DATABASE=???"
		'Conn.open DSNtest
		Conn.open(CleanConn)
	End Sub
	Public Function Combine(masterID,slaveID)
		if i_Dependz.count = 0 then
			Err.Raise vbObjectError, "Combine error" ,"No dependencies given!"
		elseif masterID = slaveID then
			Err.Raise vbObjectError, "Combine error" ,"Combine a record with itself?!"
		end if
		For Each d in i_Dependz
			Execute(updateSQL(d,i_Dependz(d),masterID,i_Dependz(d),slaveID))
		Next
		Delete(slaveID)
	End Function
	Public Function clean(input)
		'########
		'# Attempts to strip any kind of ugliness from user input (bad characters and SQL injections).
		'########
		output = Replace(Replace(Replace(Replace(Replace(Replace(Replace(input,"‘","'"),"’","'"),Chr(148),""""),Chr(147),""""),Chr(133),"..."),Chr(150),"--"),Chr(151),"--")
		output = Replace(output,"AMPERSAND","&")
		output = Replace(output,"POUNDSIGN","#")
		output = Replace(output,"COMMA",",")
		output = Replace(output,"©","©")
		output = Replace(output,"'","''")
		clean = output
	End Function
	Public Sub debugMode()
		if i_debugMode = true then
			Response.write "Debug Mode OFF!”
			i_debugMode = false
		else
			Response.write “Debug Mode ON! Queries not executed; sent to browser!”
			i_debugMode = true
		end if
	End Sub
	Public Function Delete(recordID)
		For Each d in i_Dependz
			sql = deleteSQL(d,i_Dependz(d),recordID)
			Execute(sql)
		Next
		Execute(deleteSQL(i_Table,”id”,recordID))
	End Function
	Public Function deleteSQL(table,key,value)
		deleteSQL = “DELETE FROM ” & table & ” WHERE ” & key & ” = ” & value
	End Function
	Public Function Depend(table,intersection)
		if NOT i_Dependz.exists(lcase(table)) then
			i_Dependz.Add table,intersection
		end if
	End Function
	Public Function addMany()
		dim count
		count = 0
		sep = “, ” ‘# Separator… This should probably *NOT* be changed, but it may vary I guess.
		‘***
		‘ We need to generate a ‘key’ above as a kind if placeholder, so we know how many times to Enumerate through the Querystring.
		‘***
		For Each field in i_TableArray
			if NOT is_excepted(field) and NOT is_excluded(field) and key = “” then
				if Request(field) <> “” OR Request(field) <> “” then
					key = field
				elseif right(field,4) = “Date” then
					prefix = split(field,”Date”)(0)
					if Request(prefix & “MM”) <> “” OR Request(prefix & “MM”) <> “” then
						key = prefix & “MM”
					end if
				end if
			end if
		next
		if key = “” then
‘			Err.Raise vbObjectError, “AddMany error” ,”No key generated for ” & i_Table & “!”
		else
			set previousExceptions = Server.CreateObject(”Scripting.Dictionary”)
			For Each ex in i_Exceptions		‘####
				previousExceptions.Add ex,true	‘# Necessary so previously given exceptions are not overwritten.
			Next					‘####
			For Each item in Request(key)
				For Each field in i_TableArray
					if NOT is_excluded(field) then
						if right(field,4) = “Date” then
							prefix = split(field,”Date”)(0)
							MM = Request(prefix & “MM”)
							DD = Request(prefix & “DD”)
							YYYY = Request(prefix & “YYYY”)
							if uBound(split(MM,”, “)) <> -1 then
								value = split(MM,sep)(count) & “/” & split(DD,sep)(count) & “/” & split(YYYY,sep)(count)
							else
								value = MM & “/” & DD & “/” & YYYY
							end if
						else
							values = split(Request(field),sep)
							if UBound(values) <> -1 then
								value = values(count)
							else
								value = Request(field)
							end if
						end if
						if is_excepted(field) and NOT previousExceptions.exists(lcase(field)) then
							i_Exceptions(lcase(field)) = value
						else
							exception field,value
						end if
					end if
				next
				if item <> “” then
					call Add()
				end if
				count = count + 1
			next
		end if
	end function
	Public Function is_excluded(field)
		if i_Exclusions.exists(lcase(field)) then
			is_excluded = true
		else
			is_excluded = false
		end if

	End Function
	Public Function is_excepted(field)
		if i_Exceptions.exists(lcase(field)) then
			is_excepted = true
		else
			is_excepted = false
		end if
	End Function
	Public Sub Execute(sql)
		Dim i
		if i_debugMode = true then
			response.write “Q: ” & sql & “”
			set excp = new yStr
			set excl = new yStr
			For Each i in i_Exceptions
				if excp.output() <> “” then
					excp.App(”,”)
				end if
				excp.App(i & ” = ‘” & i_Exceptions(i) & “‘”)
			Next
			For Each i in i_Exclusions
				if excl.output() <> “” then
					excl.App(”,”)
				end if
				excl.App(i & ” = ‘” & i_Exclusions(i) & “‘”)
			Next
			‘response.write “Excepts: ” & excp.output() & “”
			‘response.write “Exclude: ” & excl.output() & “”
		else
			Conn.Execute(sql)
		end if
	End Sub
	Public Function exception(fieldName,value)			‘#########
		if NOT i_Exceptions.exists(lcase(fieldName)) then	‘# Force field ‘x’ to have value ‘y’
			i_Exceptions.Add lcase(fieldName),cstr(value)		‘# -Will override form-submitted values
		end if							‘# -Will *not* override excluded fields (below)
	End Function							‘#########
	Public Function exclude(fieldName)				‘#########
		if NOT i_Exclusions.exists(lcase(fieldName)) then	‘# Ignore field
			i_Exclusions.Add lcase(fieldName),true		‘# -by default ignores ‘id’ (can’t change id!)
		end if							‘#########
	End Function
	Public Function exists(fieldName)
		if i_TableArray.exists(fieldName) = true then
			exists = true
		else
			exists = false
		end if
	End Function
	Public Function fieldsToSQL					‘##########
		dim SQL							‘# Takes table and returns SQL-digestible
		set SQL = new yStr
		For Each name in i_TableArray
			if not i_Exclusions.exists(lcase(name)) then
				if SQL.output() <> “” then
					SQL.App(”,”)
				end if
				SQL.App(name)
			end if
		Next
		fieldsToSQL = SQL.output()
	End Function
	Public Function getDataType(ByVal strValue)
		‘########
		‘# Gets the data type (varchar, int, bit, etc) of a field.
		‘# Quite handy inside and outside the class.
		‘########
		if i_TableArray.exists(strValue) then
			getDataType = i_TableArray(strValue)
		else
			getDataType = False ‘Err.Raise vbObjectError, “getDataType function error” ,”No field ‘” & strValue & “‘ within ” & i_Table
		end if
	End Function
	Public Function getValue(test)
		if i_Exclusions.exists(lcase(test)) then
			getValue = false				‘########
		else							‘# Checks excludes, exceptions, GET variables
			if i_Exceptions.exists(lcase(test)) then	‘# and returns a database-ready result.
				value = i_Exceptions(lcase(test))	‘# Internally used but useful for debugging.
			elseif IsDate(ifDate(test)) then		‘########
				value = ifDate(test)
			elseif Request(test) <> false then
				value = Request(test)
			elseif Request(test) <> false then
				value = Request(test)
			else
				value = false
			end if
			if getDataType(test) = “bit” and value <> false then
				Select Case lcase(value)
					case “yes”,”true”,”1″,”on”
						value = “True”
					case “no”,”false”,”0″,”off”
						value = “False”
				end Select
			end if
			if i_debugMode = true then
			‘	response.write “” & test & “=’” & value & “‘ | ”
			end if
			getValue = value
		end if
	End Function
	Public Function insertSQL
		‘########
		‘# Returns a tasty SQL insert query. Internally used but good for
		‘# other things as well.
		‘########
		insertSQL = “INSERT INTO ” & i_Table & ” (” & fieldsToSQL() & “) VALUES (” & valuesToSQL() & “)”
	End Function
	Public Function toXML(id)
		if i_id = “” then
			i_id = id
		end if

		if i_id <> “” then
			set i_rs = Conn.Execute(”SELECT * FROM ” & i_Table & ” WHERE id = ” & i_id)
			Set toXML = Server.CreateObject(”MSXML2.DOMDocument.3.0″)
			Set root = toXML.createNode(”element”, “Records”, “”)
			toXML.setProperty “ServerHTTPRequest”,true
			toXML.validateOnParse = False
			toXML.resolveExternals = False
			toXML.appendChild (root)
			Do while not i_rs.EOF
				Set onode = toXML.createNode(”element”, “Record”, “”)
				toXML.documentElement.appendChild (onode)
				for each x in i_rs.fields
					Set inode = toXML.createNode(”element”, x.name , “”)
					if(x <> “”) then
						if x.type = “11″ then
							if x = true then
								value=”True”
							else
								value=”False”
							end if
						else
							value = x.value
						end if
						inode.Text = value
					end if
					onode.appendChild (inode)
				next
				i_rs.movenext
			Loop
		else
			toXML = false
		end if
	End Function
	Public Sub Table(ByVal strValue)
		‘########
		‘# Declares what table we’re dealing with.
		‘# Most of this class breaks if this isn’t set first! =)
		‘########
		i_Table = strValue
		set i_TableRS = Conn.Execute(”SELECT COLUMN_NAME,DATA_TYPE FROM INFORMATION_SCHEMA.Columns WHERE TABLE_NAME = ‘” & i_Table & “‘”)
		set i_TableArray = Server.CreateObject(”Scripting.Dictionary”)
		While Not i_TableRS.EOF
			i_TableArray.Add i_TableRS(”COLUMN_NAME”).value, i_TableRS(”DATA_TYPE”).value
			i_TableRS.MoveNext
		Wend
	End Sub
	Public Function valuesToSQL
		‘########
		‘# Makes a bunch of checks to create the VALUES(. . .) in an INSERT query
		‘# Handles annoying quotes and stuff.
		‘########
		dim SQL
		set SQL = new yStr
		For Each name in i_TableArray
			if not is_excluded(name) then
				if SQL.output() <> “” then
					SQL.App(”,”)
				end if
				value = getValue(name)
				if value = false and exists(name) then
					value = “NULL”
				elseif getDataType(name) = “bit” then
					if value = “False” then
						value = “0″
					elseif value = “True” then
						value = “1″
					end if
				end if

				value = clean(value & “”)

				if NOT left(lcase(value),8) = “convert(” AND NOT left(lcase(value),5) = “cast(” AND NOT lcase(value) = “null”and NOT getDataType(name) = “int” then
					value = “‘” & value & “‘”
				end if
				SQL.App(value)
			end if
		Next
		valuesToSQL = SQL.output()
	End Function
	Public Function Update(recordID)
		i_id = cstr(recordID)
		dim insert			‘########
		dim changes			‘# Updates a particular record with form-submitted values
		dim Old				‘# and exceptions. Ignores excludes. Protects against SQL
						‘# injections and handles datatypes correctly
						‘########
		dim f
		if i_Table = “” then
			Err.Raise vbObjectError, “Update error” ,”No table set!”
		end if

		if recordID = “” then
			Err.Raise vbObjectError, “Update error” ,”Junk RecordID given! [” & recordID & “]”
		end if

		set Old = Conn.Execute(”SELECT * From ” & i_Table & ” WHERE id = ” & recordID)
		if NOT Old.EOF then
			for each f in Old.Fields
				newValue = getValue(f.Name)
				if exists(f.Name) then
					if (newValue <> false ) OR (newValue = false and getDataType(f.Name) = “datetime” and f.value <> “” and (Request(f.Name) <> false OR Request(split(f.Name,”Date”)(0) & “MM”) <> false)  ) then
						fieldName = f.Name
						if replace(clean(newValue),”””,”‘”) <> cstr(f.value & “”) then
							call updateField(fieldName,newValue,recordID)
							changes = “on”
						else
							‘Execute(”–Skipping ” & f.Name & ” (” & newValue & “|” & f.value & “)”)
						end if
					end if
				end if
			next
			if getValue(”combine”) <> “” and getValue(”combine”) <> False then
				call Combine(recordID,getValue(”combine”))
				changes = “on”
			end if
			if changes = “on” then
				Update = true
			else
				Update = false
			end if
		else
			Err.Raise vbObjectError, “Update error” ,”Record ” & recordID & ” does not exist in ” & i_Table & “!”
		end if
	end function
	Public Function updateField(field,value,recordID)
		‘####
		‘# field:	Field name to match with input value of the same name
		‘# insert:	Value submitted by the form (If its different, we’re Update()ing it.
		‘# recordID:	Get Record [id] of table [tbl] and check [field] for [insert]

		if getDataType(field) = “bit” then
			if value = “False” then
				value = “0″
			elseif value = “True” then
				value = “1″
			end if
		elseif getDataType(field) = “datetime” and value = False then
			value = “NULL”
		end if
		value = clean(value)
		if value <> “nil” then
			if lcase(value) <> “null” then
				value = “‘” & value & “‘”
			end if
			if i_debugMode = true then
				set previous = Conn.Execute(”SELECT ” & field & ” FROM ” & i_Table & ” WHERE id = ” & recordID)
				if NOT previous.EOF then
					append = ” –was ‘” & Previous.Fields.Item(field) & “‘”
				else
					append = “”
				end if
			end if
			Execute(updateSQL(i_Table,field,value,”id”,recordID) & append)
		end if
	End Function
	Public Function updateSQL(table,field,newValue,key,value)
		updateSQL = “UPDATE ” & table & ” SET ” & field & ” = ” & newValue & ” WHERE ” & key & ” = ” & value
	End Function
	Public Function Add()
		if getValue(”addedBy”) = false then
			call exception(”addedBy”,Session(”userID”))
		end if
		call exception(”timestamp”,NOW())
		Execute(insertSQL())
		i_id = lastInsertID()
		Add = i_id
	End Function
	Public Function lastInsertID()
		Set LastID = Conn.Execute(”SELECT Ident_Current(’” & i_Table & “‘) as LastID”)
		if NOT LastID.EOF then
			lastInsertID = LastID(”lastID”)
		end if
	End Function
	Private function ifDate(name)
		‘Name:		Name of form input to be tested to contain ‘Date’.
		‘		If it does match, we grab its components (MM + DD + YYYY) and return.
		‘		Elsewise, we pass false and move on with our lives.
		if right(name,4) = “Date” then
			prefix = split(name,”Date”)(0)
			if Request(prefix & “MM”) <> “” then
				MM = Request(prefix & “MM”)
				DD = Request(prefix & “DD”)
				YYYY = Request(prefix & “YYYY”)
‘			elseif Request(prefix & “MM”) <> “” then
‘				MM = Request(prefix & “MM”)
‘				DD = Request(prefix & “DD”)
‘				YYYY = Request(prefix & “YYYY”)
			end if
			if MM <> “” then
				ifDate = MM & “/” & DD & “/” & YYYY
			elseif MM = “” then
				ifDate = “NULL”
			end if
		else
			ifDate = false
		end if
	End Function
End Class
Class yXSL
	Private i_xsl
	Private i_xml
	Private i_rs
	Private i_pass
	Private Sub Class_Initialize
		if Request(”xsl”) = “” then
			i_xsl = “xsl/main.xsl”
		else
			i_xsl = “xsl/” & Request(”xsl”) & “.xsl”
		end if
		set i_pass = Server.CreateObject(”Scripting.Dictionary”)
		set Conn = CreateObject(”ADODB.Connection”)
		‘DSNtest=”DRIVER={SQL Server};SERVER=???;UID=???;PWD=???;DATABASE=???”
		‘Conn.open DSNtest
		Conn.open(CleanConn)
	End Sub
	Public Function xsl(xslFile)
		i_xsl = “xsl/” & xslFile & “.xsl”
	End Function
	Public Function xml(xmlFile)
		if isObject(xmlFile) then
			set i_xml = xmlFile
		else
			i_xml = “”
		end if
	End Function
	Public Function rs(passedRS)
		if NOT IsObject(passedRS) then
			Err.Raise vbObjectError, “RS error” ,”Junk recordset passed!”
		else
			set i_rs = passedRS
		end if
	End Function
	Public Sub outputXML()
		if IsObject(i_rs) then
			response.ContentType=”application/xml”
			response.write “< ?xml version='1.0' encoding='windows-1252'?>”
			response.write toXML().xml
		end if
	End Sub
	Public Function pass(fieldName)
		if NOT i_pass.exists(lcase(fieldName)) then
			i_pass.Add lcase(fieldName),true
		end if
	End Function
	Public Function toXML()
		Set toXML = Server.CreateObject(”MSXML2.DOMDocument.3.0″)
		Set root = toXML.createNode(”element”, “Records”, “”)
		toXML.setProperty “ServerHTTPRequest”,true
		toXML.validateOnParse = False
		toXML.resolveExternals = False
		toXML.appendChild (root)
		While not i_rs.EOF
			Set onode = toXML.createNode(”element”, “Record”, “”)
			toXML.documentElement.appendChild (onode)
			for each x in i_rs.fields
				Set inode = toXML.createNode(”element”, x.name , “”)
				if(x <> “”) then
					if x.type = “11″ then
						if x = true then
							value=”True”
						else
							value=”False”
						end if
					else
						value = x.value
					end if
					inode.Text = value
				end if
				onode.appendChild (inode)
			next
			i_rs.movenext
		Wend
	End Function
	Public Sub Transform
		Set xmlDoc = server.CreateObject(”Msxml2.FreeThreadedDOMDocument.3.0″)
		xmlDoc.async = false
		if TypeName(i_xml) <> “DOMDocument” then
			if i_xml = “null” or i_xml = “” then
				Set root = xmlDoc.createNode(”element”, “Records”, “”)
				xmlDoc.appendChild(root)
				Set onode = xmlDoc.createNode(”element”, “Record”, “”)
				xmlDoc.documentElement.appendChild (onode)
			else
				xmlDoc.load(Server.MapPath(i_xml))
			end if
		else
			xmlDoc.load(i_xml)
		end if
		xmlDoc.setProperty “ServerHTTPRequest”,true
		xmlDoc.validateOnParse = False
		xmlDoc.resolveExternals = False
		Set xslt = server.CreateObject(”MSXML2.XSLTemplate.3.0″)
		Set xslDoc = server.CreateObject(”MSXML2.FreeThreadedDOMDocument.3.0″)
		xslDoc.async = false
		xslDoc.load(server.MapPath(i_xsl))
		xslt.stylesheet = xslDoc
		Set xslProc = xslt.createProcessor()
		xslProc.input = xmlDoc
		for each req in i_pass
			value = i_pass(req)
			xslProc.addParameter req, value
		next
		for each req in Session.Contents
			value = Session(req)
			xslProc.addParameter req, value
		next
		for each req in Request.QueryString
			value = Request.QueryString(req)
			xslProc.addParameter req, value
		next
	‘	xslProc.addObject Session, “urn:ASPSession”
	‘	xmlDoc.save Server.MapPath(”saved.xml”)
		xslProc.transform
		response.write xslProc.output
	End Sub
	Public Sub toCSV(filename)
		set output = new yStr
		total = i_rs.Fields.Count
		count = 0
		for each x in i_rs.Fields
			output.App “”"” & x.name & “”"”
			if count < total then
				output.App ","
			end if
			count = count + 1
		next
		output.App vbCrLf
		While not i_rs.EOF
			set record = new yStr
			for each x in i_rs.fields
				if(isNull(x)) or x = "" then
					x = " "
				end if
				'x = Replace(x,",","\\,")
				if record.output = "" then
					record.App """" & x
				else
					record.App """,""" & x
				end if
			next
			output.App record.output & """" & vbCrLf
			i_rs.movenext
		wend
		Response.Clear()
		Set userAgent=Server.CreateObject("MSWC.BrowserType")
		if userAgent.browser = "IE" then
			Response.AddHeader "Content-Disposition","attachment;filename=export.csv"
			Response.ContentType = "text/csv"
		else
			Response.AddHeader "Content-Disposition","attachment;filename=" & Replace(filename," ","_") &".csv"
			response.ContentType = "text/csv"
		end if
		response.write output.output
		response.End
	End Sub
End Class
%>

Serving up SQL as XML to XSL document() via ASP

Thursday, March 1st, 2007

Say that 10 times fast.

I am probably the last person on earth using ASP Classic to do XSL transforms (v 1.0). I find XSL’s document() function handy to get live SQL data into the transform, and I prefer to use XSL rather than ASP to manipulate/navigate XML. This handy script accepts pseudo-SQL from XSL, builds a SQL query based on simple input, and serves up the result in XSL-edible XML.

A basic example:

xsl:variable name="pseudoSQL" select="'http://x.com/getXML.asp?fields=firstName&table=People&key=id&val=2'" 
xsl:variable name="record" select="document($pseudoSQL)/Records/Record"

(Since formatting is kinda wide, future examples start after the domain. Also, you may have to replace ‘&’ with & amp;)

How about all last names of people named ‘Jon’ or ‘Joe’

getXML.asp?field=lastName&key=first&val=jon&val=joe

How about all last names of Jons with more than 8 fingers?

getXML.asp?field=lastName&key=first&val=jon&key=fingers&val=>8

How about the top 5 people with 32 teeth, by last name?

getXML.asp?top=5&key=teeth&val=32&orderBy=last

Short of JOINs, I haven’t found too much this script can’t do. I’ve done complex grouping with counts, records between date ranges, complex date parts and CASTs, etc. Even when JOINs are neccessary, you can simply pass module=x and viola, it gives you the results of your pre-entered complex SQL (see script).

Add to Technorati Favorites

Orlando Web Design by EAI