[php][xml] Parsing element attributes

I have been using PHP for a couple years; however, I am very new to XML. The “XML Parsing using PHP” tutorials have been very helpful, but there is one thing I still cannot figure out. For instance, if an xml entry in the “Intermediate” tutorial had read…

<?xml version=“1.0”?>
<news>
<story>
<headline> Godzilla Attacks LA! </headline>
<description>Equipped with a…</description>
<author name=“John Doe” />
</story>
</news>

How then would I parse the information contained in the “name” attribute? Help with this would be greatly appreciated. Thanks!

The PHP manual has some pretty interesting comments about your problem (see http://nl2.php.net/manual/de/ref.xml.php). I’ve found the following function that might solve your problem (I don’t know about licensing though, you may want to get in touch with the author about it):


// Function xml2array
// takes an xml string and returns an array of elements
// each element is an associative array, consisting of 'name', 'test',
// possible 'attributes', sub 'elements', and closing tag if there is one.
// If there are attributes, they are also
// an associative array whose key values are the names of the attributes
// and the values are the array values
// Aerik Sylvan, Oct 27 2005
function xml2array ($xml)
{
   $xmlary = array ();

   if ((strlen ($xml) < 256) && is_file ($xml))
     $xml = file_get_contents ($xml);
  
   $ReElements = '/<(\w+)\s*([^\/>]*)\s*(?:\/>|>(.*?)<(\/\s*\1\s*)>)/s';
   $ReAttributes = '/(\w+)=(?:"|\')([^"\']*)(:?"|\')/';
  
   preg_match_all ($ReElements, $xml, $elements);
   foreach ($elements[1] as $ie => $xx) {
   $xmlary[$ie]["name"] = $elements[1][$ie];
     if ( $attributes = trim($elements[2][$ie])) {
         preg_match_all ($ReAttributes, $attributes, $att);
         foreach ($att[1] as $ia => $xx)
           // all the attributes for current element are added here
           $xmlary[$ie]["attributes"][$att[1][$ia]] = $att[2][$ia];
     } // if $attributes
     
     // get text if it's combined with sub elements
   $cdend = strpos($elements[3][$ie],"<");
   if ($cdend > 0) {
           $xmlary[$ie]["text"] = substr($elements[3][$ie],0,$cdend -1);
       } // if cdend
       
     if (preg_match ($ReElements, $elements[3][$ie])){        
         $xmlary[$ie]["elements"] = xml2array ($elements[3][$ie]);
         }
     else if (isset($elements[3][$ie])){
         $xmlary[$ie]["text"] = $elements[3][$ie];
         }
     $xmlary[$ie]["closetag"] = $elements[4][$ie];
   }//foreach ?
   return $xmlary;
} 


Good luck!

Maurits