2012-03-22 1 views
1

XML을 기반으로 Coldfusion에서 메뉴를 빌드하기 위해 노력하고 있습니다.coldfusion xml menu

현재 작업 기능 :

<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> 

나는 아이들을 위해 고려해야 나는 몇 가지 중요한 어려움으로 실행하고 있습니다. 다음은 배열과 구조체를 기반으로 사용하는 예제입니다.

<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> 

가능한 경우 재귀를 피하려고합니다. 그래서 내 질문은 부모 노드에 대한 XML 파일을 검색하고 그것에 자식 노드를 추가하는 for 루프에 블록을 추가하는 방법입니다. 나는 수색 조각에 문자 그대로 붙어있다. 지금까지 나는 위치를 찾기 위해 xmlNav.findNode=XmlSearch(myXmlDoc,"/UL/LI[@ID='id57']");을 사용하여 예를 들어 노드를 찾을 수 있지만 거기에 항목을 삽입하는 데 문제가 있습니다.

+0

여기서 질문이 있습니까? – Henry

+0

@Henry 나는 방금 더 명확하게 만들었습니다. –

+0

기본적으로 내부에있는 모든 메뉴 항목을 가진 "qGetNav"라는 쿼리가 제공되며 동적으로 XML을 생성하려고합니다. –

답변

0

많은 노력과 협업 끝에 모든 사람과 공유하고 싶습니다. 다음 두 함수는 다음 쿼리를 기반으로 XML 메뉴를 생성합니다. 나는 이것이 괴짜 커뮤니티에서 다른 사람들을 돕기를 진심으로 바란다.

<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>