使用PHP递归解析simpleXML数据

时间:2013-07-03 10:04:42

标签: recursion xml-parsing tags simplexml

我想从XML文件中读取嵌套元素和每个元素的属性值。我使用simpleXML,到目前为止我的代码是:

$path = Mage::getBaseUrl('media').'Banners/data.xml' ;
$doc = new DOMDocument();
$doc->load( $path );

$items = $doc->getElementsByTagName( "imgitem" );
$xml=simplexml_load_file($path);

foreach($xml->children() as $child)
{
  foreach( $child as $item )
    {
        $attr = $xml->imgitem->attributes();
        echo $attr['image'].'<br>';
        echo $attr['link'].'<br>';
        echo $attr['target'].'<br>';            

    }
}

有人能指出我正确的方向,以递归方式获取所有子节点及其属性吗?

这是源XML文件结构

<Banner> 
<imgitem image="img/source/path" link="" target="_blank" delay="" textBlend="yes"> <![CDATA[Autumn Leaves]]> </imgitem> 
<imgitem image="img/source/path" link="" target="_blank" delay="" textBlend="yes"> <![CDATA[Creek]]> </imgitem> 
<imgitem image="img/source/path" link="" target="_blank" delay="" textBlend="yes"> <![CDATA[Dock]]> </imgitem> 
</Banner>

现在我想要的是父标签的三个项目中每个项目的所有属性的值。因此需要遍历主标记以获取所有三个(或任意数量)项目,然后采用另一个循环并获取每个项目的所有属性值。

3 个答案:

答案 0 :(得分:1)

感谢您澄清问题。我认为你在这里过于复杂 - 这里不需要递归,你甚至可能不需要多个循环。

您已经拥有foreach($xml->children() as $child) - 这将为每个<imgitem>提供$child,因为它们是顶级项目的子项。你可以等同地说foreach($xml->imgitem as $child),它会跳过任何不是<imgitem>标签的孩子。

要回显这些元素的属性,您只需要说$child['someAttributeName'] - 所以您在示例中的代码就像这样:

$path = Mage::getBaseUrl('media').'Banners/data.xml' ;
$xml = simplexml_load_file($path);

foreach($xml->children() as $child)
{
    echo $child['image'].'<br>';
    echo $child['link'].'<br>';
    echo $child['target'].'<br>';           
}

如果不是引用特定属性,而是出于某种原因想要依次遍历每个属性,你只需要在内部再循环一次:

foreach($xml->children() as $child)
{
    foreach($child->attributes() as $attr_name => $attr_value)
    {
        echo "Attribute '$attr_name' has value '$attr_value'";
    }
}

答案 1 :(得分:1)

正在寻找类似的解决方案,在大型xml文档中以递归方式查找所有子节点。 这对我有用:

 $xmlIterator = new RecursiveIteratorIterator()
 new SimpleXMLIterator($xml_string), 
 RecursiveIteratorIterator::SELF_FIRST);
 foreach ($xmlIterator as $nodeName => $node) {
   echo "<br>" . $nodeName, $node['attribute'], PHP_EOL;
 }

答案 2 :(得分:0)

如果在前面添加第二个),则此示例有效在第一行代码中。它列出了XML文件根目录中的所有节点及其所有子节点。

$xmlIterator = new RecursiveIteratorIterator(new SimpleXMLIterator($xmlstring,RecursiveIteratorIterator::SELF_FIRST));
foreach ($xmlIterator as $nodeName => $node)
{
    echo "<br>" . $nodeName, $node['value'], PHP_EOL;
}