I have found a solution that I think works pretty well. I created a java
class that leverages XPath functionality. I then created the following
custom CFML XmlSearch wrapper method that calls my java code:
<cffunction name="xmlSearch" access="public" returntype="array">
<cfargument name="xmlDoc" type="xml" hint="CFML XML Object" />
<cfargument name="expression" type="string" hint="XPath search
expression" />
<cfset var xPathReader = CreateObject(
"java","com.daveshuck.xpath.XPathReader" ).init( arguments.xmlDoc ) />
<cfset var xPathConstants =
CreateObject("java","javax.xml.xpath.XPathConstants") />
<cfset var result = xPathReader.read( arguments.expression,
xPathConstants.NODESET ) />
<cfset var returnArray = []>
<cfset var i = 0 />
<cfloop condition="i LT result.getLength()">
<cfset ArrayAppend( returnArray, result.item( i ) ) />
<cfset i++ />
</cfloop>
<cfreturn returnArray />
</cffunction>
I can pass this function a CFML XML object and xpath expression, and it
returns an array of nodes, just like ACF XmlSearch(). However, there are
caveats. If anyone has any input on the following, I would appreciate it.
- Under the covers, it is doing XML validation, and I haven't yet figured
out how to make it quite. I had to remove the <!DOCTYPE> declaration from
all Mach-II config files as I get the following exception as it
automatically tries to validate: *access denied
(java.net.SocketPermission www.mach-ii.com:80 connect,resolve)*. I
imagine that I am going to discover a way to make it ignore validation, but
if not, is there a workaround to that java.netSocketPermission error?
- I originally attempted to simply add my function to the
*component.cfc*under WEB-INF/bluedragon. However, I never could get
my application to
recognize the method. Is this perhaps similar to the situation with the
*customjars-GAE* folder, where you have to add them there rather than the
WEB-INF/lib directory when using the OBD Desktop? In my case - at least as
of now - I have resorted to adding the method to the
MachII.framework.BaseComponent class, and making the AppFactory,
PropertyManager, ListenerManager, etc... extend BaseComponent. It isn't
elegant, but it will get the job done. The big question though, is how can
I add this as a custom method to OpenBD?
- I am not even going to pretend to know how this will work under heavy
load. I am a hack of a Java developer, and I wouldn't be surprised at all
to learn that I did something stupid.
Is this something that would be worthy of adding to the engine for GAE
specifically? I am certainly open to contributing if so, but have no idea
how that would work.
@dshuck
--
official tag/function reference: http://openbd.org/manual/
mailing list - http://groups.google.com/group/openbd?hl=en