<cffunction name="CSSElementSelectorToXPath" access="public" returntype="string" output="false" hint="I convert a single element selector to XPath (ex. div.header)."> <!--- Define arguments. ---> <cfargument name="Selector" type="string" required="true" hint="I am the single element selector." /> <!--- Define the local scope. ---> <cfset var LOCAL = {} /> <!--- Trim the selector and remove any pseudo selector information. While some of these can be applied (ex. :event), for our purposes, we are not going to apply them at this time. ---> <cfset LOCAL.Selector = Trim( REReplace( ARGUMENTS.Selector, ":[^\s]*", "", "one" ) ) /> <!--- Check to see what kind of pattern we have here. As far as CSS is concerned, we really only have six different selectors to care about: element#id element.class #id .class *.class * ---> <cfif REFind( "^\w+##.+$", LOCAL.Selector )> <!--- Return ID selector. ---> <cfreturn ( ListFirst( LOCAL.Selector, "##" ) & "[ @id = """ & ListLast( LOCAL.Selector, "##" ) & """ ]" ) /> <cfelseif REFind( "^\w+\..+$", LOCAL.Selector )> <!--- Return class selector. ---> <cfreturn ( ListFirst( LOCAL.Selector, "." ) & "[ contains( @class, """ & ListLast( LOCAL.Selector, "." ) & """ ) ]" ) /> <cfelseif REFind( "^##.+$", LOCAL.Selector )> <!--- Return ANY ID selector. ---> <cfreturn ( "*[ @id = """ & ListLast( LOCAL.Selector, "##" ) & """ ) ]" ) /> <cfelseif REFind( "^\..+$", LOCAL.Selector )> <!--- Return ANY class selector. ---> <cfreturn ( "*[ contains( @class, """ & ListLast( LOCAL.Selector, "." ) & """ ) ]" ) /> <cfelseif REFind( "^\*\..+$", LOCAL.Selector )> <!--- Return ANY class selector. ---> <cfreturn ( "*[ contains( @class, """ & ListLast( LOCAL.Selector, "." ) & """ ) ]" ) /> <cfelseif REFind( "^\w+$", LOCAL.Selector )> <!--- Return element selector. ---> <cfreturn LOCAL.Selector /> <cfelse> <!--- Not valid - return ANY selector. ---> <cfreturn "*" /> </cfif> </cffunction>