试图让 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>
除了 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
我有 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>
除了 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