试图让循环中的XML getElementsByTagName + getAttribute调用工作

I have this overly complicated XML dump by Eatec, and sadly each menu has it's own special attribute for meals served at breakfast/lunch/dinner. I'm trying to extract the items with their description and do a loop to show only recipe from breakfast, and so on for other menu periods.

Here's a sample slimmed down 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>

And I'm relatively new to PHP/XML, still trying to learn my rope here, here's what I came up with and yet not been able to keep the looped item within it's own meal period.

 <?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>';

Instead of showing meals for breakfast and lunch in their own loop, it's loading every recipe regarding what meal period is. Am I making it too complicated ? that I got lost by my own code?

I think you tangled yourself

$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>' ."
";
   echo '<h3 class="location_date">'.$recipes->getAttribute('location').'</h3>'  ."
";  
   $recipe_type = $recipes->getAttribute("mealperiodname");
   echo '<h3 class="location_date">'.$recipe_type.'</h3>' ."
"; 

   echo '  <div class="meal_items">' . "
";
   foreach($recipes->getElementsByTagName("recipe") as $recipe_item) {
      echo '    <p class="item_list"><a alt="" href="#">' .
           $recipe_item->getAttribute("description") .
           '</a></p>'  ."
";
   }        
   echo '  </div>' ."
";
}

result

<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>

demo

It is rather confusing if you name a variable $recipes = $menu->getElementsByTagName("menu"); but I think inside of the foreach( $recipes as $recipe ) you want to use $mrecipes = $recipe->getElementsByTagName('recipe') to select on the inner recipe elements contained in the menu element.

Additionally to the DOM Api methods, you can use Xpath to fetch parts of the DOM tree. Xpath allows for conditions, so you can fetch all the menu nodes for a specific meal period.

Here is an example that outputs the information as text.

$mealPeriods = [
  'Breakfast',
  'Lunch'
];

$document = new DOMDocument();
$document->loadXml($xml);
$xpath = new DOMXpath($document);

// iterate the meal periods
foreach ($mealPeriods as $mealPeriod) {
  echo $mealPeriod, "
=====================
";

  // fetch all menu element nodes for a specific meal period
  $expression = "/data/menu[@mealperiodname = '$mealPeriod']";
  foreach ($xpath->evaluate($expression) as $menu) {
    echo "
", $menu->getAttribute('location'), "
---------------------
";

    // 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'), "
";
    }
  } 
  echo "
";  
}

Output:

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