【问题标题】:Trying to get XML getElementsByTagName + getAttribute call in loop to work试图让循环中的 XML getElementsByTagName + getAttribute 调用工作
【发布时间】:2016-07-08 09:14:13
【问题描述】:

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

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

它不是在自己的循环中显示早餐和午餐的餐点,而是加载有关用餐时间的每个食谱。我让它太复杂了吗?我被自己的代码迷路了吗?

【问题讨论】:

    标签: php xml dom getelementsbytagname getattribute


    【解决方案1】:

    我觉得你自己纠结了

    $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

    【讨论】:

    • 感谢这按预期进行!是的,我知道我很亲密,但就像你说的那样完全纠结。
    【解决方案2】:

    如果您将变量命名为 $recipes = $menu-&gt;getElementsByTagName("menu"); 会相当混乱,但我认为您想在 foreach( $recipes as $recipe ) 内部使用 $mrecipes = $recipe-&gt;getElementsByTagName('recipe') 来选择包含在 menu 元素中的内部 recipe 元素。

    【讨论】:

      【解决方案3】:

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

      【讨论】:

      • 我尝试运行它,但语法错误在 'evaluate($expression)' 处停止
      猜你喜欢
      • 2023-03-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-08-21
      • 1970-01-01
      • 1970-01-01
      • 2012-11-11
      • 2016-07-06
      相关资源
      最近更新 更多