У меня есть этот слишком сложный дамп XML от Eatec, и, к сожалению, у каждого меню есть свой особый атрибут для блюд, которые подаются на завтрак / обед / ужин. Я пытаюсь извлечь элементы с их описанием и сделать цикл, чтобы показать только рецепт с завтрака, и так далее для других периодов меню.
Вот пример уменьшенного XML
<data>
<menu name="location breakfast" servedate="20160626" location="food court 1" mealperiodname="Breakfast" >
<recipes>
<recipe id="5626935" category="HOT MORNING GRAINS" description="Oatmeal RD">
</recipe>
<recipe id="5371796" category="HOT MORNING GRAINS" description="Rice Brown RD">
</recipe>
</recipes>
</menu>
<menu name="location lunch" servedate="20160626" location="food court 2" mealperiodname="Lunch">
<recipes>
<recipe id="4430587" category="SOUPS" description="Soup Tomato w/Garden Vegetables">
</recipe>
<recipe id="4210899" category="SOUPS" description="Soup Beef Barley w/Vegetables">
</recipe>
</recipes>
</menu>
</data>
И я относительно новичок в PHP / XML, все еще пытаюсь изучить мою веревку здесь, вот то, что я придумал, и все же не смог сохранить зацикленный элемент в течение своего собственного периода приема пищи.
<?php
$menu = new DOMDocument();
$breakfast = 'Breakfast';
$lunch = 'Lunch';
$menu->load("http://amphl.org/test.xml");
// Get location name
$menu_get = $menu->getElementsByTagName("menu");
$location_name = $menu_get->item(0)->getAttribute("location");
$menu_period = $menu_get->item(0)->getAttribute("name");
// Get menus
$recipes = $menu->getElementsByTagName("menu");
$recipe_items = $menu->getElementsByTagName("recipe");
// echo tests
echo '<h3 class="location_date">'.$menu_period.'</h3>';
echo '<h3 class="location_date">'.$location_name.'</h3>';
echo '<div class="meal_items">';
// echo '<h3 class="food_name"> Breakfast </h3>';
foreach( $recipes as $recipe )
{
// Get recipe name
$recipe_type = $recipe->getAttribute("mealperiodname");
echo '<h3 class="location_date">'.$recipe_type.'</h3>';
if ($recipe_type == $breakfast) {
foreach( $recipe_items as $recipe_item )
{
$recipe_name = $recipe_item->getAttribute("description");
echo '<p class="item_list"><a alt="" href="#">'.$recipe_name.'</a></p>';
}
}
else if ($recipe_type == $lunch) {
foreach( $recipe_items as $recipe_item )
{
$recipe_name = $recipe_item->getAttribute("description");
echo '<p class="item_list"><a alt="" href="#">'.$recipe_name.'</a></p>';
}
}
}
echo '</div>';
Вместо того, чтобы показывать еду на завтрак и обед в отдельном цикле, он загружает каждый рецепт относительно того, какой период приема пищи. Я делаю это слишком сложным? что я заблудился из-за собственного кода?
Я думаю, что вы запутались
$menu = new DOMDocument();
$breakfast = 'Breakfast';
$lunch = 'Lunch';
libxml_use_internal_errors(true);
$menu->load("http://amphl.org/test.xml");
foreach($menu->getElementsByTagName("menu") as $recipes) {
echo '<h3 class="location_date">'. $recipes->getAttribute('servedate') .'</h3>' ."\n";
echo '<h3 class="location_date">'.$recipes->getAttribute('location').'</h3>' ."\n";
$recipe_type = $recipes->getAttribute("mealperiodname");
echo '<h3 class="location_date">'.$recipe_type.'</h3>' ."\n";
echo ' <div class="meal_items">' . "\n";
foreach($recipes->getElementsByTagName("recipe") as $recipe_item) {
echo ' <p class="item_list"><a alt="" href="#">' .
$recipe_item->getAttribute("description") .
'</a></p>' ."\n";
}
echo ' </div>' ."\n";
}
результат
<h3 class="location_date">20160626</h3>
<h3 class="location_date">food court 1</h3>
<h3 class="location_date">Breakfast</h3>
<div class="meal_items">
<p class="item_list"><a alt="" href="#">Oatmeal RD</a></p>
<p class="item_list"><a alt="" href="#">Rice Brown RD</a></p>
</div>
<h3 class="location_date">20160626</h3>
<h3 class="location_date">food court 2</h3>
<h3 class="location_date">Lunch</h3>
<div class="meal_items">
<p class="item_list"><a alt="" href="#">Soup Tomato w/Garden Vegetables</a></p>
<p class="item_list"><a alt="" href="#">Soup Beef Barley w/Vegetables</a></p>
</div>
Это довольно запутанно, если вы называете переменную $recipes = $menu->getElementsByTagName("menu");
но я думаю, что внутри foreach( $recipes as $recipe )
ты хочешь использовать $mrecipes = $recipe->getElementsByTagName('recipe')
выбрать на внутренней recipe
элементы, содержащиеся в menu
элемент.
В дополнение к методам DOM Api вы можете использовать Xpath для извлечения частей дерева DOM. Xpath учитывает условия, поэтому вы можете выбрать все узлы меню для определенного периода приема пищи.
Вот пример, который выводит информацию в виде текста.
$mealPeriods = [
'Breakfast',
'Lunch'
];
$document = new DOMDocument();
$document->loadXml($xml);
$xpath = new DOMXpath($document);
// iterate the meal periods
foreach ($mealPeriods as $mealPeriod) {
echo $mealPeriod, "\n=====================\n";
// fetch all menu element nodes for a specific meal period
$expression = "/data/menu[@mealperiodname = '$mealPeriod']";
foreach ($xpath->evaluate($expression) as $menu) {
echo "\n", $menu->getAttribute('location'), "\n---------------------\n";
// iterate the recipe element nodes for a specific menu
foreach ($xpath->evaluate('recipes/recipe', $menu) as $recipe) {
echo '#', $recipe->getAttribute('id'), ' ';
echo $recipe->getAttribute('description'), "\n";
}
}
echo "\n";
}
Выход:
Breakfast
=====================
food court 1
---------------------
#5626935 Oatmeal RD
#5371796 Rice Brown RD
Lunch
=====================
food court 2
---------------------
#4430587 Soup Tomato w/Garden Vegetables
#4210899 Soup Beef Barley w/Vegetables