访问SimpleXML节点的XML属性

I have a XML file as following:

<menus>
    <defaultMenu>
        <group>
            <menuItem name="Example one" url="http://www.google.com">
                <menuItem name="Example Two" url="http://www.yahoo.com" />
                <menuItem name="Example Three" url="http://www.bing.com" />
            </menuItem>
        </group>
    </defaultMenu>
</menus>

I want to loop over the <menuItem> tags to gather all URLs, but didn't found how to access the attributes of a SimpleXML node.

Here is the code I tried without success :

$contentXML = simplexml_load_file('file.xml');
$urls = array();

foreach($xml->menus->defaultMenu->group->menuItem as $menuItem) {
    $urls[] = $menuItem->url;
}

However, this method is not the right, as the array only get empty values after the loop. So, how do I access the XML attributes of a SimpleXML node ?

To access the attributes of a SimpleXML node, you have to use the node object as an array. Example:

foreach($contentXML->menus->defaultMenu->group->menuItem as $menuItem) {
    $urls[] = $menuItem["url"];
}

See the basic usage page of the PHP documentation.

You can also use the attributes() method on the node, but that's quite verbose.

Use the children() and attributes() methods:

foreach($contentXML->menus->defaultMenu->group->menuItem->children() as $menuItem) {

    $urls[] = $menuItem->attributes()['url']; // (PHP v >= 5.4)

    $attrs = $menuItem->attributes(); // (PHP v < 5.4)
    $urls[] = $attrs['url']; 

}

Doc

Use xpath to select all url-attributes in a simple way without iterating over the XML.
xpath is like SQL for XML:

$xml = simplexml_load_string($x); // assume XML in $x

$urls = $xml->xpath("//*[@url]/@url");

You are done. See it working: https://eval.in/159586

Comments:

The xpath-expression reads as:

  • //* wherever in the hierarchy, select whatever node...
  • [@url] that has the attribute url...
  • /@url and return the attribute url only.

$urls is an array of SimpleXml-Objects, cast to stringif necessary, e.g. when making comparisons.