79506

coldfusion xml menu

Question:

I am working to build a menu in coldfusion based on xml.

current working function:

<cffunction name="xmlNav" access="private" returntype="struct" output="false"> <cfargument name="qGetNav" type="query" required="true"> <cfscript> var qNav=Arguments.qGetNav; var xmlNav=StructNew(); var myXmlDoc=xmlNew(); var route=''; myXmlDoc.XMLRoot = XMLElemNew(myXmlDoc,"UL"); myXmlDoc.UL.xmlAttributes.ID="nav-main-links"; for(q=1;q<=qNav.recordCount;q++){ //setup li myXmlDoc.UL.XmlChildren[q]=XmlElemNew(myXmlDoc,"LI"); myXmlDoc.UL.XmlChildren[q].xmlAttributes.ID="id" & qNav["navid"][q]; myXmlDoc.UL.XmlChildren[q].xmlAttributes.CLASS="standby"; //setup route myXmlDoc.UL.XmlChildren[q].a=XmlElemNew(myXmlDoc,"A"); route=qNav["Route"][q]; if(qNav["Version"][q] Eq "CB"){ route="/?event=" & route; } else if(qNav["Version"][q] Eq "L"){ route="http://" & route; } myXmlDoc.UL.XmlChildren[q].A.xmlAttributes.HREF=route; myXmlDoc.UL.XmlChildren[q].A.xmlAttributes.TARGET=qNav["LinkTarget"][q]; myXmlDoc.UL.XmlChildren[q].A.xmlAttributes.TITLE=qNav["LinkTitle"][q]; //setup route text myXmlDoc.UL.XmlChildren[q].A.SPAN=XmlElemNew(myXmlDoc,"SPAN"); myXmlDoc.UL.XmlChildren[q].A.SPAN.xmlText=qNav["TextDesc"][q]; myXmlDoc.UL.XmlChildren[q].A.SPAN.FONT=XmlElemNew(myXmlDoc,"FONT"); myXmlDoc.UL.XmlChildren[q].A.SPAN.FONT.xmlAttributes.CLASS="menuItemType"; myXmlDoc.UL.XmlChildren[q].A.SPAN.FONT.xmlText="(" & qNav["Version"][q] & ")"; } xmlNav.xmlNavString=toString(myXmlDoc); xmlNav.xmlNavString=replaceNoCase(xmlNav.xmlNavString,"&gt;",CHR(62),"all"); xmlNav.xmlNavString=replaceNoCase(xmlNav.xmlNavString,"&lt;",CHR(60),"all"); xmlNav.xmlNavString=replaceNoCase(xmlNav.xmlNavString,"&amp;",CHR(38),"all"); xmlNav.xmlNav=myXmlDoc; return xmlNav; </cfscript> </cffunction>

I need to account for children and I am running into some significant difficulty. Here is the example I am using based on arrays and structs:

<cffunction name="arrayNav" access="private" returntype="struct" output="false"> <cfargument name="qGetNav" type="query" required="true"> <cfscript> var qNav=Arguments.qGetNav; var arrayNav=StructNew(); var aNavTree = arrayNew(1); var aNavMenuItems = arrayNew(1); var sNavLookup = structNew(); for(q=1;q<=qNav.recordCount;q++){ sThis = structNew(); sThis.data = structNew(); sThis.data.navid = qNav["navid"][q]; sThis.data.Route = qNav["Route"][q]; sThis.data.Version = qNav["Version"][q]; if(qNav["Version"][q] Eq "CB"){ arrayAppend(aNavMenuItems,qNav["Route"][q]); } sThis.data.LinkTarget = qNav["LinkTarget"][q]; sThis.data.LinkTitle = qNav["LinkTitle"][q]; sThis.data.TextDesc = qNav["TextDesc"][q]; sThis.children = arrayNew(1); /* now loop through avoid dupes from the levelid, this should prob be handled in the query above by only selecting the right levels, or using a select distinct without the levelid in there */ if(Not structKeyExists(sNavLookup,qNav["navid"][q])){ sNavLookup[qNav["navid"][q]] = sThis; } else{ //do nothing } if(qNav["NavParentId"][q] EQ 0){ arrayAppend(aNavTree, sThis); } else{ if(structKeyExists(sNavLookup, qNav["NavParentId"][q])){ arrayAppend(sNavLookup[qNav["NavParentId"][q]].children, sThis); } else{ //parent not found } } } arrayNav.arrayNav=aNavTree; arrayNav.arrayNavMenuItems=aNavMenuItems; return arrayNav; </cfscript> </cffunction>

hoping to avoid recursion if I can. so my question is how can add a block to the for loop that searches the xml file for the parent node and adds children nodes to it. I am literally stuck on the search piece. so far I can find the node for example using xmlNav.findNode=XmlSearch(myXmlDoc,"/UL/LI[@ID='id57']"); to find the position, but having trouble inserting the item there.

Answer1:

After a ton of effort and collaboration, I want to share this with everyone. The following 2 functions generate an xml menu based on a the following query. I truly hope this helps others in the geek community.

<cfquery name="qGetNav" datasource="pcmenusqldev"> select navid,navparentid,navorder,Route,Version,LinkTarget,LinkTitle,TextDesc from rhNavRoutesByLevel,rhnavRoutes where rhnavRoutes.ID=rhNavRoutesByLevel.NavID And LevelID = 1 order by navParentId, navOrder, navId </cfquery> <cfset aNav = buildNav(qgetNav)> <cfdump var="#qgetNav#" label="qGetNav" expand="no"> <cfdump var="#buildNav(qGetNav)#" expand="no" label="buildNav"> <hr><hr><hr> <cfset testme=structnew()> <cfset testme.menu=buildListXML(aNav)> <cfdump var="#testme#"> <hr><hr><hr> <cfoutput>#buildListXML(aNav)#</cfoutput> <hr><hr><hr> <cfoutput>#buildList(aNav)#</cfoutput> <cffunction name="buildNav" returntype="array"> <cfargument name="qGetNav" type="query"> <cfset var sLU = structNew()> <cfset var aMenu = arrayNew(1)> <cfset var aNavMenuItems = arrayNew(1)> <cfset var sThis = structNew()> <cfloop query="qGetNav"> <cfset sThis = structNew()> <cfset sThis.route = qGetNav.Route> <cfset sthis.textDesc = qGetNav.textDesc> <cfset sthis.linkTitle = qGetNav.linkTitle> <cfset sthis.linkTarget = qGetNav.linkTarget> <cfset sthis.Version = qGetNav.version> <cfif sthis.Version Eq "CB"> <cfset arrayAppend(aNavMenuItems,sThis.route)> </cfif> <cfset sthis.navID = qGetNav.navID> <cfset sthis.aChildren = arrayNew(1)> <cfset sLU[qGetNav.navID] = sThis> <cfif val(qGetNav.navParentID) NEQ 0> <cfset arrayAppend(sLU[qGetNav.navParentID].aChildren, sThis)> <cfelse> <cfset arrayAppend(aMenu, sThis)> </cfif> </cfloop> <cfreturn aMenu> </cffunction> <cffunction name="buildListXML" returntype="xml"> <cfargument name="aNav" type="array"> <cfset var navXML=""> <cfxml variable="navXML"> <cfoutput> #buildList(aNav=arguments.aNav)# </cfoutput> </cfxml> <cfreturn navXML> </cffunction> <cffunction name="buildList" returntype="any"> <cfargument name="aNav" type="array"> <cfset var iNav = ""> <ul> <cfloop array="#aNav#" index="iNav"> <cfoutput> <cfif iNav.Version Eq "CB"> <cfset iNav.Route="/?event=" & iNav.Route> <cfelseif iNav.Version Eq "L"> <cfset iNav.Route="http://legacy" & iNav.Route> </cfif> <li class="standby" id="id#iNav.navid#"> <a href="#iNav.route#" title="#iNav.linkTitle#" target="#iNav.linkTarget#"> #iNav.textDesc# <font class="menuItemType">(#iNav.Version#)</font> </a> <cfif arrayLen(iNav.aChildren) GT 0> <cfset buildList(iNav.aChildren)> </cfif> </li> </cfoutput> </cfloop> </ul> </cffunction>

Recommend

  • Writing CDATA in ASP.NET WebApi
  • get all elements of xml body and add to struct
  • Liferay Dynamic Data Lists: How to get image URL?
  • How to swap two XML elements in linq to xml
  • PHP Script in my Wordpress Files. Please Decode or Help Me Remove it [closed]
  • Towers of Hanoi with “counter” in python
  • How do I make openssl_encrypt pad the input to the required block size?
  • Deserialize XML string to complex type
  • text-align justify, cannot override
  • Angular - routerLinkActive and queryParams handling
  • Is it possible to get the word under the mouse cursor in a ``?
  • How to use an array of arrays with array_map(…) in PHP?
  • Xamarin Forms - UWP Fonts
  • Insert into database using onclick function
  • Different response to non-authenticated users and AJAX calls
  • jQuery show() function is not executed in Safari if submit handler returns true
  • How to draw moving and Running sine wave chart using JFree chart in java?
  • output of program is not same as passed argument
  • Incrementing object id automatically JS constructor (static method and variable)
  • MySQL WHERE-condition in procedure ignored
  • How to apply VCL Styles to DLL-based forms in Inno Setup?
  • Change an a tag attribute in JavaScript based on screen width
  • Eraser for UIBezierPath
  • How to limit post in wp_query
  • Upload files with Ajax and Jquery
  • Build own AppleScript numerical error handling
  • Web-crawler for facebook in python
  • Unanticipated behavior
  • AngularJs get employee from factory
  • trying to dynamically update Highchart column chart but series undefined
  • Java static initializers and reflection
  • Exception on Android 4.0 `android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode)`
  • Change div Background jquery
  • Bitwise OR returns boolean when one of operands is nil
  • Is there any way to bind data to data.frame by some index?
  • Django query for large number of relationships
  • Why is Django giving me: 'first_name' is an invalid keyword argument for this function?
  • How can I use `wmic` in a Windows PE script?
  • java string with new operator and a literal
  • How to push additional view controllers onto NavigationController but keep the TabBar?