Discussion:
Looping over an XML Dynamic Menu File
(too old to reply)
murpg
2005-12-28 14:46:44 UTC
Permalink
I have created a dynamic menu using ColdFusion and XML. I have run into a
little problem. The menu works great except I am trying to use a pipe |
delimiter to sperate the items in the menu. I don't want to use a pipe
delimiter on my last menu item. I have put an IF statement saying not to use a
PIPE delimiter on the last menu item. It puts it there anyway. I am including
my menu builder and the XML file. It is very short code.

Copy and paste code call file (_main_build_mainrev.cfm) have it in the same
directory as the XML file and you will see what I mean.

<!--- get the current folder --->
<cfset current_dir = getDirectoryFromPath(getTemplatePath())>
<!--- read XML file --->
<cffile
action="read"
file="#current_dir#afrtsmenu.xml"
variable="themenu">
<!--- parse the XML into an array --->
<cfset menu = xmlparse(themenu)>
<!--- <cfdump var="#menu#"> --->

<cfoutput>
<ul>
<!--- loop through the array and get top level items --->
<cfloop index="ls" from="1" to="#arraylen(menu.afrtsmenu.XmlChildren)#">
<!--- loop through the array and get 2nd level items --->

<cfloop index="it" from="1"
to="#arraylen(menu.afrtsmenu.list[ls].XmlChildren)#">
<li><a href="#menu.afrtsmenu.list[ls].item[it].link.XmlText#"
class="nav"> #menu.afrtsmenu.list[ls].item[it].display_text.XmlText#</a><cfif
it LT arraylen(menu.afrtsmenu.XmlChildren)>&nbsp;|&nbsp;<cfelse></cfif></li>
<!--- if not last child then add a seperator --->
</cfloop>
</cfloop>
</ul>
</cfoutput>

This is the XML file call it (afrtsmenu.xml)

<?xml version="1.0"?>
<afrtsmenu>

<list>
<item id="1">
<display_text>HOME</display_text>
<link><![CDATA[index.cfm?ParentID=1&ContentParentID=1]]></link>
</item>
</list>

<list>
<item id="2">
<display_text>FAQ</display_text>
<link><![CDATA[index.cfm?ParentID=2&ContentParentID=1]]></link>
</item>
</list>

<list>
<item id="3">
<display_text>DECODER REPAIRS</display_text>
<link><![CDATA[index.cfm?ParentID=3&ContentParentID=1]]></link>
</item>
</list>

<list>
<item id="4">
<display_text>CONTACT US</display_text>
<link><![CDATA[index.cfm?ParentID=4&ContentParentID=1]]></link>
</item>
</list>

<list>
<item id="5">
<display_text>TRUSTED USERS</display_text>
<link><![CDATA[index.cfm?ParentID=5&ContentParentID=1]]></link>
</item>
</list>

<list>
<item id="6">
<display_text>SYSTEM SETUP</display_text>
<link><![CDATA[index.cfm?ParentID=6&ContentParentID=1]]></link>
</item>
</list>
</afrtsmenu>
BKBK
2005-12-28 16:40:56 UTC
Permalink
Replace

<cfif it LT arraylen(menu.afrtsmenu.XmlChildren)>&nbsp;|&nbsp;<cfelse></cfif>

with

<cfif it LT arraylen(menu.afrtsmenu.list[ls].XmlChildren)>&nbsp;|&nbsp;</cfif>
murpg
2005-12-28 18:52:53 UTC
Permalink
HI BKBK,

I tried what you suggested. I don't get any pipe delimited symbols now. Did you get a chance to run the code? It is just 2 files saves and a launching of the menu builder.
Umbrae
2005-12-28 19:40:39 UTC
Permalink
You may want to try outputting #it# and ArrayLen to try and debug. BKBK is
right (if we understand what you are trying to do), and the only way this would
not show pipes is if #it# was GTE the ArrayLen.
murpg
2005-12-29 13:08:16 UTC
Permalink
Already tried many different combinations including looking at the value of
#it# and ArrayLen. The value of arraylen(menu.afrtsmenu.XmlChildren) is 6.
The value of #ls# is 6. The value of
arraylen(menu.afrtsmenu.list[ls].XmlChildren) is 1.

The value of #it# is 1. Not quite sure why the last 2 values are 1. Can
anyone please help me debug this arraylen(menu.afrtsmenu.list[ls].XmlChildren)?
Umbrae
2005-12-29 13:45:30 UTC
Permalink
Ok, so this means that 1 = 1; therefore, your code it working by not showing
any Pipes. This means there is only 1 element in
menu.afrtsmenu.list[ls].XmlChildren. You can use CFDUMP to look at the actual
XML object to try and debug.

I think your problem is the layout of your XML which does not follow the logic
you are using to build your menu. I "ASSUME" you want pipes between your <list>
items, but you cannot use ArrayLen in the loop you are trying too since all
<list> items only contain one <item> item.

Rethink your logic of how you are looping through the XML and how the XML
document is structured.
murpg
2005-12-29 15:08:43 UTC
Permalink
Dear Mr. Umbrae,

I have spent 2 days trying to work out the logic on this. I would not have
come to this forum if I could have figured out the logic so easily. I am
asking for help. Can someone PLEASE help me with this. Let's start with the
app that I am using to build the XML. Here is the code for it. I am not quite
sure how to make all of the items be a children of the list.



<cfquery name="ListParentsContent" datasource="AFRTS">
SELECT ParentLocs.ParentID, ParentLocs.ParentName, AFRTSContent.ContentID,
AFRTSContent.ContentName, AFRTSContent.ContentParentID
FROM ParentLocs, AFRTSContent
</cfquery>
<CFSET xmldoc = "<?xml version=""1.0""?>
<afrtsmenu>
">
<CFLOOP query="ListParentsContent">
<CFSET xmldoc = xmldoc & "
<list>
<item id=""#Trim(XMLFormat(ParentID))#"">
<display_text>#Trim(XMLFormat(ParentName))#</display_text>

<link><![CDATA[index.cfm?ParentID=#Trim(XMLFormat(ParentID))#&ContentID=#Trim(XM
LFormat(ContentID))#&ContentParentID=#Trim(XMLFormat(ContentParentID))#]]></link
</item>
</list>
">
</CFLOOP>
<CFSET xmldoc = xmldoc & "</afrtsmenu>">
<CFSET filename= ExpandPath("./") & "afrtsmenu.xml">
<CFFILE action="write" file="#filename#" output="#xmldoc#">
Umbrae
2005-12-29 16:48:59 UTC
Permalink
murpg,

I understand and appreciate your frustration. However, a lot of people coming
here wanting others to write code for them. Therefore, unless I personally
believe something is very challenging, I do not write code for people or layout
the exact answer on the table. If you want the work done for you, I would be
happy to barter on a consulting fee.

Otherwise, it is in your best interest to resolve as much of this by yourself.
I am not trying to be mean; just make you a better programmer.

You may need to step back from this for a second. Don't worry about how you
are generating the XML. Just look at the static document you originally posted.
Your problem is either:

1. Your XML is not organized to work the way you have coded.
- or -
2. Your code is not thinking about how the XML is formatted.

The main problem is the code snip:

<cfloop index="ls" from="1" to="#arraylen(menu.afrtsmenu.XmlChildren)#">
<!--- loop through the array and get 2nd level items --->

<cfloop index="it" from="1"
to="#arraylen(menu.afrtsmenu.list[ls].XmlChildren)#">
<li><a href="#menu.afrtsmenu.list[ls].item[it].link.XmlText#"
class="nav"> #menu.afrtsmenu.list[ls].item[it].display_text.XmlText#</a><cfif
it LT arraylen(menu.afrtsmenu.XmlChildren)>&nbsp;|&nbsp;<cfelse></cfif></li>
<!--- if not last child then add a seperator --->
</cfloop>
</cfloop>

I assume you want this:

HOME | FAQ | DECODER REPAIRS | CONTACT US | TRUSTED USERS | SYSTEM SETUP

Otherwise, I may not understand what you are trying to do at all. If this is
correct, then you just need to look where the data is in the XML document and
which piece you are trying to call from which CFLOOP.
murpg
2005-12-29 18:53:36 UTC
Permalink
Dear Mr Umbrae,

Please do not lecture to me. I am not a child. I just asked for help with
something that I am not very familiar with. You probably already know the
answer to my problem but you would rather waste your time and mine by lecturing
me instead of just helping out and answering my question. I am not looking for
you to code the whole problem just tell me to change this line to that and be
done with it.

If that is not what you are interested in doing please don't respond because
there are too many other wonderful programmers out there who are more than
willing to help when a person asks for it. Now is there somone out there who
can help me with my problem generating this XML ColdFusion menu?
Umbrae
2005-12-29 20:46:01 UTC
Permalink
Well my my... I was not lecturing. I just took 4 lines to explain why I, and
why many others, will not feed you the answer. I have in two posts pointed you
to the spot in your code where you were in error and explained what you need to
look at and think about to resolve your issue. It is not my fault you are not
willing to work on the answer. I could write code for you all day, but in the
end it does not help you; nor do I get compensated for my time.

If you think you can get anyone else to help you by insulting them, feel free
to keep trying. Just remember how many times I tried to help you, and how many
others have posted on this thread.

Good Luck.
murpg
2005-12-29 22:58:37 UTC
Permalink
Dear Mr. Umbraie,

I am grateful for all of the help that I get from this forum. I have had
people really help me when I needed it. I have found another solution. Thank
you for your time. You are truly in the Holiday Spirit. The best to you,
Happy New Year. I decided to add a | pipe to the beginning.

Loading...