Я анализирую документ XHTML, используя PHP SimpleXML. Мне нужно запросить серию ul в документе для узла, содержащего определенное значение, а затем найти прямой родительский узел этого узла ... код поможет объяснить!
Учитывая следующий фиктивный xhtml:
<html>
<head></head>
<body>
...
<ul class="attr-list">
<li>Active Life (active)</li>
<ul>
<li>Amateur Sports Teams (amateursportsteams)</li>
<li>Amusement Parks (amusementparks)</li>
<li>Fitness & Instruction (fitness)</li>
<ul>
<li>Dance Studios (dancestudio)</li>
<li>Gyms (gyms)</li>
<li>Martial Arts (martialarts)</li>
<li>Pilates (pilates)</li>
<li>Swimming Lessons/Schools (swimminglessons)</li>
</ul>
<li>Go Karts (gokarts)</li>
<li>Mini Golf (mini_golf)</li>
<li>Parks (parks)</li>
<ul>
<li>Dog Parks (dog_parks)</li>
<li>Skate Parks (skate_parks)</li>
</ul>
<li>Playgrounds (playgrounds)</li>
<li>Rafting/Kayaking (rafting)</li>
<li>Tennis (tennis)</li>
<li>Zoos (zoos)</li>
</ul>
<li>Arts & Entertainment (arts)</li>
<ul>
<li>Arcades (arcades)</li>
<li>Art Galleries (galleries)</li>
<li>Wineries (wineries)</li>
</ul>
<li>Automotive (auto)</li>
<ul>
<li>Auto Detailing (auto_detailing)</li>
<li>Auto Glass Services (autoglass)</li>
<li>Auto Parts & Supplies (autopartssupplies)</li>
</ul>
<li>Nightlife (nightlife)</li>
<ul>
<li>Bars (bars)</li>
<ul>
<li>Dive Bars (divebars)</li>
</ul>
</ul>
</ul>
...
</body>
</html>
Мне нужно иметь возможность запросить список ul.attr для дочернего элемента и обнаружить его «корневую» категорию. Я не могу изменить xhtml, чтобы он формировался по-другому.
Итак, если у меня есть «галереи» в качестве категории, мне нужно знать, что она относится к категории «искусство» «корневая». Или, если у меня есть «dog_parks», мне нужно знать, что он находится в категории «активные». Следующий код выполняет работу, но только при условии, что в максимуме есть два вложенных уровня:
function get_root_category($shortCategoryName){
$url = "http://www.yelp.com/developers/documentation/category_list";
$result = file_get_contents($url);
$dom = new domDocument();
@$dom->loadHTML($result);
$dom->preserveWhiteSpace = false;
$sxml = simplexml_import_dom($dom);
$lvl1 = $sxml->xpath("//li[contains(., '".$shortCategoryName."')]/parent::ul/preceding-sibling::li");
$lvl2 = $sxml->xpath("//li[contains(., '".$shortCategoryName."')]/parent::ul/preceding-sibling::li/parent::ul/preceding-sibling::li");
if($lvl2){
return array_pop($lvl2);
} else {
return array_pop($lvl1);
}
}
Должен существовать лучший способ написания этого XPath, так что требуется выполнить только один запрос, и он является пуленепробиваемым для нескольких вложенных уровней.
EDIT :: Спасибо тем, кто указал, что этот HTML-код недействителен. Однако структура страницы задана, и я не могу ее редактировать; Я могу использовать его только как ресурс, и я должен сделать то, что есть.