coldfusion xml menu

拟墨画扇 提交于 2020-01-14 04:15:37

问题


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.


回答1:


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>


来源:https://stackoverflow.com/questions/9832256/coldfusion-xml-menu

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!