Page 1 of 1

Addressing elements in multi-dimensional arrays from XML

Posted: Sun Dec 19, 2010 12:25 pm
by verrips
Hi

I'm trying to "flatten" an XML into a single Array. My problem is within the XML I have attributes that are mapped to different elements in the desired Array. How to I "address" these elements?

A sample is attached - I'm looking to correct the following lines of code:

Code: Select all

	        $flat_out['phone_home'] = $record->phones->phone->attributes('type')->home;
		$flat_out['phone_work'] = $record->phones->phone->attributes('type')->work;
		$flat_out['phone_mobile'] = $record->phones->phone->attributes('type')->mobile;
Full sample below.

I know I can use extract data with a foreach or if loop, but hoping to find out how to address the elements directly.

Thanks SO much!

Code: Select all

<?php
$xml_file = '
<response>
	<individual id="1007">
	<first_name>Andy</first_name>
	<last_name>Appletree</last_name>
	<phones>
		<phone type="home">555 1234</phone>
		<phone type="mobile">121 1212</phone>
	</phones>
	</individual>
	<individual id="1207">
	<first_name>Betty</first_name>
	<last_name>Base</last_name>
	<phones>
		<phone type="work">888 9999</phone>
		<phone type="mobile">999 1818</phone>
	</phones>
	</individual>
</response>';

$flat_out = Array (
	'id', 
	'first_name', 
	'last_name', 
	'phone_home', 
	'phone_work', 
	'phone_mobile');
 
$xml = simplexml_load_string($xml_file);

foreach ($xml->individual as $record) {
		$flat_out['id'] = $record->attributes()->id;
		$flat_out['first_name'] = $record->first_name;
		$flat_out['last_name'] = $record->last_name;
		$flat_out['phone_home'] = $record->phones->phone->attributes('type')->home;
		$flat_out['phone_work'] = $record->phones->phone->attributes('type')->work;
		$flat_out['phone_mobile'] = $record->phones->phone->attributes('type')->mobile;
		print_r ($flat_out);
}
/**
Output looks as follows:
Array
( 
    [id] => 1007
    [first_name] => Andy
    [last_name] => Appletree
    [phone_home] => 
    [phone_work] => 
    [phone_mobile] =>  
)

Array
(
    [id] => 1207
    [first_name] => Betty
    [last_name] => Base
    [phone_home] => 
    [phone_work] => 
    [phone_mobile] => 
)
**/


Re: Addressing elements in multi-dimensional arrays from XML

Posted: Sun Dec 19, 2010 6:59 pm
by requinix

Code: Select all

$flat_out['phone_home'] = $record->phones->phone->attributes('type')->home;
$flat_out['phone_work'] = $record->phones->phone->attributes('type')->work;
$flat_out['phone_mobile'] = $record->phones->phone->attributes('type')->mobile;
Doesn't work like that. What you're doing now is getting the "home" value of the "type" attribute. That doesn't make sense; compare it with getting the value of the element whose "type" attribute is "home".

You can use XPath to do a search:

Code: Select all

$home = current($record->phones->xpath("phone[@type='home']"));
$flat_out["phone_home"] = ($home ? (string)$home : "");

Re: Addressing elements in multi-dimensional arrays from XML

Posted: Mon Dec 20, 2010 7:21 am
by verrips
Thanks tasairis - I tried it, and it works great! XPath is exactly what I was looking for, what a blessing! Thanks again!