Я работаю над созданием меню в Coldfusion на основе XML.
текущая рабочая функция:
<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,">",CHR(62),"all");
xmlNav.xmlNavString=replaceNoCase(xmlNav.xmlNavString,"<",CHR(60),"all");
xmlNav.xmlNavString=replaceNoCase(xmlNav.xmlNavString,"&",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>
в надежде избежать рекурсии, если смогу. поэтому мой вопрос - как добавить блок в цикл for, который ищет в XML-файле родительский узел и добавляет к нему дочерние узлы Я буквально застрял на поиске. до сих пор я могу найти узел, например, используя xmlNav.findNode=XmlSearch(myXmlDoc,"/UL/LI[@ID='id57']");
, чтобы найти позицию, но не могу вставить элемент туда.