У меня есть некоторые иерархические данные, которые мне нужно отобразить в серии вложенных UL. Для каждого элемента у меня есть имя, идентификатор и значение глубины. Обычно я просто группирую эти элементы по глубине, но на самом деле мне нужно создать древовидную структуру с моими данными, например:
Вот мой вопрос: есть ли хороший способ для создания правильной разметки (мне бы очень хотелось, чтобы она распечатывалась и с правильными табуляциями, но это будет сложно), где мои данные будут упакованы во вложенные UL? У меня уже есть решение, которое вроде работает, но я получаю один случайный тег . Вот код, который у меня есть для этого:
<?php
include("includes/classes/Database.class.php");
$db = new Database();
$query = "SELECT COUNT(parent.Name) - 2 as level, node.Name AS Name, node.ID
FROM Region AS node, Region AS parent
WHERE node.LeftVal BETWEEN parent.LeftVal AND parent.RightVal and node.Name <> 'Earth'
GROUP BY node.ID
ORDER BY node.LeftVal";
$results = $db->executeQuery($query);
?>
<!DOCTYPE HTML>
<html lang="en-US">
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
<?php
$last_level = 0;
?>
<ul id="regionTree">
<?php
while ($row = mysql_fetch_assoc($results)) {
$link = '<li>'.PHP_EOL.'<a href="addChild.php?parentid='.$row["ID"].'">'.$row["Name"]."</a>".PHP_EOL;
$diff = $last_level - $row["level"];
if($diff == 0){
// Sibling
echo ($row["level"] != 0) ? '</li>'.PHP_EOL.$link:$link;
}
elseif($diff < 0){
// Child
$demoter = '<ul>'.PHP_EOL;
for ($i=0; $i > $diff; $i--) {
echo $demoter;
}
echo $link;
}
else{
// Parent
$promoter = '</li>'.PHP_EOL.'</ul>';
for ($i=0; $i < $diff; $i++) {
echo ($row["level"] != 0) ? $promoter.PHP_EOL."</li>":$promoter;
}
echo $link;
}
$last_level = $row["level"];
}
?>
</li>
</ul>
</body>
</html>
Есть идеи?
:: Edit ::
Я создал pastebin с сгенерированным источником, который не проверяет.
Pastebin.com
:: РЕДАКТИРОВАТЬ 2 ::
Вот схема для таблицы Region. Он разработан с использованием гибридной модели вложенного множества и модели списка смежности.
CREATE TABLE Region (
ID INT UNSIGNED NOT NULL AUTO_INCREMENT COMMENT 'Stores the ID for the Region.',
Name VARCHAR(45) NOT NULL COMMENT 'Stores the name of the Region',
Region_Type VARCHAR(45) NOT NULL COMMENT 'Stores the Region type.',
Parent INT COMMENT 'Stores the ID of the Parent Region',
LeftVal INT NOT NULL,
RightVal INT NOT NULL,
PRIMARY KEY (ID)
) COMMENT 'Stores information about all Regions.' ENGINE=INNODB
ROW_FORMAT=DEFAULT CHARACTER SET utf8 collate utf8_general_ci;