Programming Forums
User Name Password Register
 

RSS Feed
FORUM INDEX | TODAY'S POSTS | UNANSWERED THREADS | ADVANCED SEARCH

Reply
 
Thread Tools Display Modes
Old Jun 23rd, 2006, 11:06 AM   #1
niteice
Programmer
 
niteice's Avatar
 
Join Date: Aug 2005
Posts: 98
Rep Power: 4 niteice is on a distinguished road
Send a message via AIM to niteice
SimpleXML issues

I have an XML document describing a section of a site I'm coding. I'm already using it to generate a page, but now I need to also use it to generate a navigation bar. The documents is structured like so:
<downloads>
	<category name="blah">
		<section name="blah">
			<file name="blah" size="somenumber" link="someurl" />
		</section>
	</category>
	<category name="blah2>
	...etc
The code generates a downloads page using <section> and <file>. Now I'm generating a navigation bar using <category>. Unfortunately, there always seems to be an off-by-one error when I'm looping through the data. My XML parser is SimpleXML. The code I have currently is:
function generateNav()
{
	$data = simplexml_load_file("data/downloads.xml");
	$out = "";

	for($i = 1; $i <= count($data->category); $i++)
	{
		$out .= "<a href=\"downloads.php?c=$i\">".$data->category[$i]["name"]."</a> ";
	}

	return $out;
}
But it will, for some reason, only show the second category link. I've tried various other combinations, which produce weird numbers or just don't display anything at all. Inexplicably, count($data->category) seems to return either 1 or nothing., even though there's 4 <category> tags in the file.
niteice is offline   Reply With Quote
Old Jun 23rd, 2006, 11:36 AM   #2
DaWei
Resident Grouch
 
DaWei's Avatar
 
Join Date: Jun 2005
Posts: 6,453
Rep Power: 10 DaWei is on a distinguished road
Consider using print_r to see what you get for $data and its constituents. Information is key to debugging. Information is there for the viewing, if you look.
__________________
Abstraction doesn't make it impossible to write bad code; it makes it possible to write superior code.
Contributor's Corner: Grumpy on C++ Exceptions DaWei on Pointers
DaWei is offline   Reply With Quote
Old Jun 23rd, 2006, 12:18 PM   #3
niteice
Programmer
 
niteice's Avatar
 
Join Date: Aug 2005
Posts: 98
Rep Power: 4 niteice is on a distinguished road
Send a message via AIM to niteice
Hmm...print_r shows the document tree the way I expected it to- category[0] through category[3]. Yet count($data->category) still says there's 1 element, when there should be 4. Is there a better way to find the number of elements in the array?

I also tried foreach(). The problem with that is that I need the array index to correctly generate the navigation link.
niteice is offline   Reply With Quote
Old Jun 23rd, 2006, 12:22 PM   #4
DaWei
Resident Grouch
 
DaWei's Avatar
 
Join Date: Jun 2005
Posts: 6,453
Rep Power: 10 DaWei is on a distinguished road
Can you post here what you get with the print_r, as well as the class definition for data?
__________________
Abstraction doesn't make it impossible to write bad code; it makes it possible to write superior code.
Contributor's Corner: Grumpy on C++ Exceptions DaWei on Pointers
DaWei is offline   Reply With Quote
Old Jun 23rd, 2006, 12:35 PM   #5
niteice
Programmer
 
niteice's Avatar
 
Join Date: Aug 2005
Posts: 98
Rep Power: 4 niteice is on a distinguished road
Send a message via AIM to niteice
$data isn't a class per se - instead, SimpleXML parses the XML into a structure that can be sort of read like a class. First attachment is the print_r output, second is some sample data structured the same way.
Attached Files
File Type: txt print_r.txt (4.5 KB, 12 views)
File Type: txt downloads.txt (861 Bytes, 12 views)
niteice is offline   Reply With Quote
Old Jun 23rd, 2006, 2:50 PM   #6
DaWei
Resident Grouch
 
DaWei's Avatar
 
Join Date: Jun 2005
Posts: 6,453
Rep Power: 10 DaWei is on a distinguished road
First off, arrays are based at 0. Your loop should not begin at 1.

Okay, here is my take on the rest, and my fix. Please understand that I am not a PHP expert. While $data->category is an array, I believe it is being treated, first, as an object. Count will not work on objects, but will return a 1. (There is a method of making objects countable, but I didn't delve into that.) In order to get around the problem, I used foreach to copy 'category' into another array. I then got the count from that array, and produced the links. Here is my code:
<?php
function generateNav()
{
	$data = simplexml_load_file("data.xml");
	foreach ($data->category as $thangy) $myArray [] = $thangy;
	$out = "";
	for($i = 0; $i < count ($myArray); $i++)
		$out .= "<a href=\"downloads.php?c=$i\">".$data->category[$i]["name"]."</a><br/> ";
	return $out;
}
echo generateNav ();
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<title>Huh!</title>
</head>
<body>

</body>
</html>
Here is my output:
Quote:
Originally Posted by Output
Some category
Some Other Category
Yet Another Category
God Damn How Many Categories Are There
__________________
Abstraction doesn't make it impossible to write bad code; it makes it possible to write superior code.
Contributor's Corner: Grumpy on C++ Exceptions DaWei on Pointers
DaWei is offline   Reply With Quote
Old Jun 23rd, 2006, 3:05 PM   #7
niteice
Programmer
 
niteice's Avatar
 
Join Date: Aug 2005
Posts: 98
Rep Power: 4 niteice is on a distinguished road
Send a message via AIM to niteice
For some reason your original foreach didn't work, so it becomes:
function generateNav()
{
	$data = simplexml_load_file("data/downloads.xml");
	$out = "";
	$i = 0;

	foreach ($data->category as $cat)
	{
		$categories[$i++] = $cat;
	}

	for($j = 0; $j < count ($categories); $j++)
	{
		$k = $j + 1;
		$out .= "<a href=\"downloads.php?c=$k\">".$data->category[$j]["name"]."</a><br/> ";
	}

	return $out;
}
I also needed the URLs to start at 1 instead of 0 because of how the rest of the code works, hence $k. At any rate, it now works how I wanted, thanks for the help.
niteice is offline   Reply With Quote
Old Jun 23rd, 2006, 3:18 PM   #8
DaWei
Resident Grouch
 
DaWei's Avatar
 
Join Date: Jun 2005
Posts: 6,453
Rep Power: 10 DaWei is on a distinguished road
Worked for me. That's how it produced the output. You can invoke the page (code shown above) here. Perhaps you didn't renew your right to use the variable, $thangy (tm DaWei).
__________________
Abstraction doesn't make it impossible to write bad code; it makes it possible to write superior code.
Contributor's Corner: Grumpy on C++ Exceptions DaWei on Pointers
DaWei is offline   Reply With Quote
Old Jun 23rd, 2006, 3:30 PM   #9
niteice
Programmer
 
niteice's Avatar
 
Join Date: Aug 2005
Posts: 98
Rep Power: 4 niteice is on a distinguished road
Send a message via AIM to niteice
Aha, my browser somehow cut out the [] after $myArray.
niteice is offline   Reply With Quote
Old Jun 23rd, 2006, 5:00 PM   #10
DaWei
Resident Grouch
 
DaWei's Avatar
 
Join Date: Jun 2005
Posts: 6,453
Rep Power: 10 DaWei is on a distinguished road
Here's a way that doesn't waste time copying the array:
   $i = 0;
   foreach ($data->category as $cat) $i++;
   for ($j = 0; $j < $i; $j++)
   {
      blah blah do da stuff...
__________________
Abstraction doesn't make it impossible to write bad code; it makes it possible to write superior code.
Contributor's Corner: Grumpy on C++ Exceptions DaWei on Pointers
DaWei is offline   Reply With Quote
Reply

Bookmarks

« Previous Thread in Forum | Next Thread in Forum »

Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)
 
Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Forum Jump




DaniWeb IT Discussion Community
All times are GMT -5. The time now is 10:02 PM.

Powered by vBulletin® Version 3.7.0, Copyright ©2000 - 2009, Jelsoft Enterprises Ltd.
Copyright ©2007 DaniWeb® LLC