我现在正处于foreach炼狱之中,试图想出一种方法来使用PHP遍历这个XML文件(下面的实际XML文本)(遵循XML文件内容)。 我想要做的是以下几点:
gallerylist.xml:
<?xml version="1.0" encoding="ISO-8859-1"?>
<gallerylisting exists="yes">
<folder subfolder="yes">
Events
<folder subfolder="yes">
Beach_Clean_2010
<folder subfolder="no">
Onna_Village
</folder>
<folder subfolder="no">
Sunabe_Sea_Wall
</folder>
</folder>
</folder>
<folder subfolder="no">
Food_And_Drink
</folder>
<folder subfolder="no">
Inside
</folder>
<folder subfolder="no">
Location
</folder>
<folder subfolder="no">
NightLife
</folder>
</gallerylisting>
gallerylisting.php
<?php
$xmlref = simplexml_load_file("gallerylisting.xml");
foreach($xmlref->children() as $child) {
foreach($child->attributes() as $attr => $attrVal) {
print $child;
if($attrVal == "yes") {
foreach($child->children() as $child) {
echo $child;
foreach($child->attributes() as $attr => $attrVal) {
if($attrVal == "yes") {
foreach($child->children() as $child) {
echo $child;
}
}
}
}
}
}
}
我...计数... 5个foreach循环深入到这个PHP脚本中我根本不喜欢它,加上如果我的文件夹有另一个子文件夹,我将不得不添加相同的
$if(attrVal=="yes")...etc.
再次,好吧......不!无论如何,我可以避免这种情况。我是PHP的新手,特别是PHP和XML。
感谢您的帮助。
答案 0 :(得分:5)
递归可能对你有益。
<?php
function display_entities( $xml )
{
foreach($xml->children() as $child) {
foreach($child->attributes() as $attr => $attrVal) {
print $child;
if($attrVal == "yes") {
display_entities( $child->children() );
}
}
}
}
$xmlref = simplexml_load_file("gallerylisting.xml");
display_entities($xmlref->children());
答案 1 :(得分:2)
使用XPath:
如果subfolder = no在叶子中不可靠(即可能不总是设置'no'):
foreach($xmlref->xpath('//folder[not(@subfolder) or @subfolder!="yes"]') as $node){
如果是:
foreach($xmlref->xpath('//folder[@subfolder="no"]') as $node){
或者即使你想要检查没有文件夹子项的文件夹,也不管属性:
foreach($xmlref->xpath('//folder[not(folder)]') as $node){
答案 2 :(得分:0)
您可以尝试使用xpath而不是嵌套循环方法..
运行查询
gallerylisting//folder[@subfolder="yes"]/text()
使用this xpath tester在上面给出的xml doc上的给出了结果Events和Beach_Clean_2010,这是我认为你想要的。查询将查找根节点gallerylisting下的所有文件夹元素,如果它们的子文件夹属性等于“yes”,则将返回节点中的文本。
所以,在PHP中,我们有
<?php
$xmldoc = new DOMDocument();
$xmldoc->load('gallerylisting.xml');
$xpathvar = new Domxpath($xmldoc);
$queryResult = $xpathvar->query('gallerylisting//folder[@subfolder="yes"]/text()');
foreach($queryResult as $result){
echo $result->textContent;
}
?>
我不是PHP人,所以我相信this StackOverflow question中的代码。需要注意的一点是,在xpath中使用// name意味着找到与当前位置匹配的所有节点。这在大型文档上可能非常慢。
似乎有多种方法可以用PHP处理xpath。来自this page的示例执行查询,如下所示:
$result = $xml->xpath("gallerylisting//folder[@subfolder="yes"]/text()");
print_r($result);
?>