PHP 和 XML。使用 PHP 循环遍历 XML 文件

Posted

技术标签:

【中文标题】PHP 和 XML。使用 PHP 循环遍历 XML 文件【英文标题】:PHP and XML. Looping through an XML file with PHP 【发布时间】:2011-10-13 19:52:31 【问题描述】:

我现在正沉浸在 foreach 炼狱中,试图想出一种方法来用 php 遍历这个 XML 文件(下面的实际 XML 文本)(遵循 XML 文件内容。) 我想做的是以下几点:

    获取所有文件夹元素名称 如果文件夹元素具有“是”作为子文件夹属性,则向下移动一个级别并获取该文件夹元素的名称 如果不移动到下一个文件夹元素

画廊列表.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。

感谢您的帮助。

【问题讨论】:

当你用效率标记这个问题时,我会提出这一点。您的 xml 中不需要“子文件夹”属性。 PHP-Library 将帮助您了解该节点是否有子节点。如果有,请递归使用@Matt 的函数。您不应该将“文本”元素(例如您的文件夹名称)与节点混合。这看起来有点恶心。尝试使用“名称”属性。 注意以备将来参考!谢谢你的坦率! (badump ch!) 【参考方案1】:

您可以尝试使用xpath 代替嵌套循环方法..

运行查询

gallerylisting//folder[@subfolder="yes"]/text() 

在上面给出的 xml 文档中,使用 this xpath tester 会给出结果事件和 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 *** question 中的代码可以正常工作。需要注意的一件事是,在 xpath 中使用 //name 意味着查找从当前位置下降并与该名称匹配的所有节点。这在大型文档上可能非常慢。

似乎有多种方法可以用 PHP 处理 xpath。来自this page 的示例执行如下查询:

   $result = $xml->xpath("gallerylisting//folder[@subfolder="yes"]/text()");

   print_r($result);
?> 

【讨论】:

【参考方案2】:

递归在这里可能对你有益。

<?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());

【讨论】:

我将不得不尝试你的交易,这个 xpath Wrikken 在下面谈论。到时我会给出我的答案。这似乎是我会在 javascript 中做的事情,所以是的,它还很遥远。 是的!是的!这就是它兄弟,这完全是它。我在实际调用它时在 display_entities 参数中做了一些小改动,我只使用了 $xmlref。这让我得到了一切!你是邪恶的兄弟。 您应该使用一个标志并将 if 移出内部 foreach 循环,否则内部 display_entitties 可能会被多次调用,而只有真的需要每个孩子一次。【参考方案3】:

使用 XPath:

如果 subfolder=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)

【讨论】:

我将不得不研究 xpath 的考验。它看起来很合法。

以上是关于PHP 和 XML。使用 PHP 循环遍历 XML 文件的主要内容,如果未能解决你的问题,请参考以下文章

php如何解析多级xml报文?

xml用php解析是重命名php文件吗

如何循环访问和访问多维和关联数组中的各种元素? PHP,JSON 或 XML

PHP 创建与解析 XML

foreach 循环中的逗号分隔变量到 php 脚本中的 xml 行

如何在循环中发送多个 SOAP 请求:PHP?