Я сейчас нахожусь на колене в чистом чистилище прямо сейчас, пытаясь придумать способ протестировать этот XML-файл (фактический текст XML ниже) с помощью PHP (после содержимого файла XML). Я пытаюсь сделать следующее:
gallerylist.xml:
<?xml version="1.0" encoding="ISO-8859-1"?> <gallerylisting exists="yes"> <folder subfolder="yes"> Events <folder subfolder="yes"> Beach_Clean_2010 <folder subfolder="no"> Onna_Village </folder> <folder subfolder="no"> Sunabe_Sea_Wall </folder> </folder> </folder> <folder subfolder="no"> Food_And_Drink </folder> <folder subfolder="no"> Inside </folder> <folder subfolder="no"> Location </folder> <folder subfolder="no"> NightLife </folder> </gallerylisting>
gallerylisting.php
<?php $xmlref = simplexml_load_file("gallerylisting.xml"); foreach($xmlref->children() as $child) { foreach($child->attributes() as $attr => $attrVal) { print $child; if($attrVal == "yes") { foreach($child->children() as $child) { echo $child; foreach($child->attributes() as $attr => $attrVal) { if($attrVal == "yes") { foreach($child->children() as $child) { echo $child; } } } } } } }
Я … подсчитываю … 5 foreach петли глубоко в этот скрипт PHP, и мне это совсем не нравится, плюс, если у моих папок была другая подпапка, мне пришлось бы добавить это
$if(attrVal=="yes")...etc.
снова и хорошо … нет! В любом случае, я могу избежать этого. Я новичок в PHP, и особенно PHP и XML.
Спасибо за любую помощь.
Рекурсия может быть полезной для вас здесь.
<?php function display_entities( $xml ) { foreach($xml->children() as $child) { foreach($child->attributes() as $attr => $attrVal) { print $child; if($attrVal == "yes") { display_entities( $child->children() ); } } } } $xmlref = simplexml_load_file("gallerylisting.xml"); display_entities($xmlref->children());
Использовать XPath:
Если вложенная папка = нет ненадежна в листьях (т. Е. «Нет» может не всегда устанавливаться):
foreach($xmlref->xpath('//folder[not(@subfolder) or @subfolder!="yes"]') as $node){
Если это:
foreach($xmlref->xpath('//folder[@subfolder="no"]') as $node){
Или даже если вы хотите полностью проверить папки без детей папок, не считая атрибута:
foreach($xmlref->xpath('//folder[not(folder)]') as $node){
Вы можете попробовать использовать xpath вместо метода вложенных циклов.
Выполнение запроса
gallerylisting//folder[@subfolder="yes"]/text()
на вашем xml-документе, указанном выше, используя этот тестер xpath, вы получите результаты Events и Beach_Clean_2010, которые, как я думаю, вам нужны. Запрос найдет все элементы папок в списке галерей корневого узла, и если у них есть атрибут подпапки, равный «да», текст в узле будет возвращен.
Итак, в PHP мы имеем
<?php $xmldoc = new DOMDocument(); $xmldoc->load('gallerylisting.xml'); $xpathvar = new Domxpath($xmldoc); $queryResult = $xpathvar->query('gallerylisting//folder[@subfolder="yes"]/text()'); foreach($queryResult as $result){ echo $result->textContent; } ?>
Я не парень PHP, поэтому я доверяю коду в этом вопросе StackOverflow . Одна вещь, о которой нужно помнить, заключается в том, что использование // name в xpath означает найти все узлы, спускаемые с текущей позиции, которые соответствуют имени. Это может быть очень медленно на больших документах.
Кажется, существует несколько способов обработки xpath с PHP. Пример из этой страницы делает запрос следующим образом:
$result = $xml->xpath("gallerylisting//folder[@subfolder="yes"]/text()"); print_r($result); ?>