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

Trying to get XML getElementsByTagName + getAttribute call in loop to work

我有 Eatec 的这个过于复杂的 XML 转储,遗憾的是每个菜单都有它自己的特殊属性,用于在 breakfast/lunch/dinner 提供的餐点。我正在尝试提取带有描述的项目,并进行循环以仅显示早餐的食谱,等等其他菜单时段。

这是一个精简的示例 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>';

它不是在自己的循环中显示早餐和午餐的膳食,而是加载关于用餐时间的每个食谱。我是不是太复杂了?我被自己的代码搞糊涂了?

如果您将变量命名为 $recipes = $menu->getElementsByTagName("menu"); 会相当混乱,但我认为在 foreach( $recipes as $recipe ) 内部您想在内部 [=] 上使用 $mrecipes = $recipe->getElementsByTagName('recipe') 到 select menu 元素中包含 13=] 个元素。

我觉得你自己纠结了

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

demo

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