views:

236

answers:

4

I'm trying to parse the XML below so that I wind up with an array that looks like the sample included... I'm having a hard time figuring out how to get the attributes inside of the tags to output the way I want it to...

The XML

<cust rid="999999" memberid="12345" lname="Doe" fname="John">
    <address memberid="12345" address1="1234 Mockingbird Lane" address2="" city="Oakland" state="CA" zip="91111" country="United States"/>
    <phone memberid="12345" phonenumber="415.555.1212" countrycodeid="1" phonetype="Mobile"/>
    <custcode memberid="12345" ccode="Silver" deleted=”1”/>
    <custcode memberid="12345" ccode="Gold"/> 
</cust>

The Array I want :: Note the added array elements

Array
    [cust] => Array
     [rid] => 999999
     [member_id] => 12345
     [lname] => Doe
     [fname] => John
     [address] => Array
      [0] => Array
       [memberid] => 12345
       [address1] => 1234 Mockingbird Lane
       [address2] =>
       [city] => Oakland
       [state] => CA
       [zip] => 91111
       [country] => United States
     [phone] => Array
      [0] => Array
       [memberid] => 12345
       [phonenumber] => 415.555.1212
       [countrycodeid] => 1
       [phonetype] => Mobile
     [custcode] => Array
      [0] => Array
       [memberid] => 12345
       [ccode] => Silver
       [deleted] => 1
      [1] => Array
       [memberid] => 12345
       [ccode] => Gold
+1  A: 

You should try using DOM. There are several dom2array functions in the comments and if they don't work for you, they can give you further ideas.

Marko
+3  A: 

You can use DOMDocument and its fields/methods to extract the data.

DOMDocument is also DOMNode has a field called attributes which is a map of attribute name and the node of value so you can get the attribute name and value from it (#6-9). Each node alos have firstChild and next sibling which you can navigate through all sub nodes (#12-26).

From that you can create array of data accordingly. Here is the code I used (with a bit adjustments).

/*01*/ function Parse($XMLNode, $XMLData = null) {
/*02*/     if ($XMLData == null)
/*03*/     $XMLData = array();
/*04*/     
/*05*/     // Extract attribute as the array values
/*06*/     if ($XMLNode->hasAttributes()) {
/*07*/         foreach ($XMLNode->attributes as $AttrName => $AttrNode)
/*08*/             $XMLData[$AttrName] = $AttrNode->nodeValue;
/*09*/     }
/*10*/     
/*11*/     // Loop all child
/*12*/     $Child = $XMLNode->firstChild;
/*13*/     while ($Child != null) {
/*14*/         $Name = $Child->nodeName;
/*15*/         if ($Name != "#text") { // Ignore the text
/*16*/             $Nodes = $XMLData[$Name];
/*17*/             if ($Nodes == null)
/*18*/                 $Nodes = array();   // Array value from subnode is a nest array
/*19*/             
/*21*/             $Nodes[] = Parse($Child);
/*22*/             $XMLData[$Name] = $Nodes;
/*23*/         }
/*24*/         
/*25*/         $Child = $Child->nextSibling;
/*26*/     }
/*27*/     return $XMLData;
/*28*/ }
/*29*/ 
/*31*/ $XML = <<<EOF
/*32*/ <cust rid="999999" memberid="12345" lname="Doe" fname="John">
/*33*/     <address memberid="12345" address1="1234 Mockingbird Lane" address2="" city="Oakland" state="CA" zip="91111" country="United States" />
/*34*/     <phone memberid="12345" phonenumber="415.555.1212" countrycodeid="1" phonetype="Mobile" />
/*35*/     <custcode memberid="12345" ccode="Silver" deleted="1" />
/*36*/     <custcode memberid="12345" ccode="Gold" /> 
/*37*/ </cust>
/*38*/ EOF;
/*39*/ 
/*41*/ $DOC = new DOMDocument();
/*42*/ $DOC->loadXML($XML);
/*43*/ $Data = Parse($DOC->firstChild);
/*44*/ 
/*45*/ print_r($Data);

The above code returns the result as you expected.

Hope this helps.

NawaMan
+1  A: 

If you are using PHP 5, use SimpleXML. It is much cleaner, easier to use and faster than DOM. If you using PHP 4, you have to use DomXML and not Dom.

Kris Erickson
A: 

NawaMan's answer is probably what you need, but if you want to simplify your PHP DOM code generally, you can also consider the jQuery-inspired phpQuery.

eyelidlessness