I'm trying to create XML from an array in the following format
<root>
<kyero>
<feed_version>3</feed_version>
</kyero>
<property>
<id>12367</id>
<date>2013-09-27 12:00:10</date>
<ref>V3TEST</ref>
<price>250000</price>
<currency>EUR</currency>
<price_freq>sale</price_freq>
<leasehold>0</leasehold>
<type>villa</type>
<town>almunecar</town>
<province>granada</province>
<country>spain</country>
<location>
<latitude>36.728807</latitude>
<longitude>-3.693466</longitude>
</location>
<features>
<feature>good rental potential</feature>
<feature>near beach</feature>
<feature>water possible</feature>
</features>
<notes>Private property notes</notes>
<images>
<image id="1">
<url>http://images.kyero.com/12811577_large.jpg</url>
</image>
<image id="2">
<url>http://images.kyero.com/12811578_large.jpg</url>
</image>
<image id="3">
<url>http://images.kyero.com/12811579_large.jpg</url>
</image>
<image id="4">
<url>http://images.kyero.com/12811581_large.jpg</url>
</image>
<image id="50">
<url>http://images.kyero.com/12811582_large.jpg</url>
</image>
</images>
</property>
</root>
The important take away is the nested arrays such as <features>
and <images>
.
An example of my array that I've built so far is:
Array
(
[kyero] => Array
(
[feed_version] => 3
)
[0] => Array
(
[id] => 2024
[ref] => jtl-2024-4202
[date] => 2019-11-19 15:34:39
[title] => A wonderful property
[price] => 14828
[price_freq] => month
[country] => United Kingdom
[location] => Array
(
[latitude] => 55.311512
[longitude] => -2.9378154999999
)
[features] => Array
(
[0] => Prominent Building
[1] => Great Location
[2] => Grade A Office Space
[3] => Air Conditioning
[4] => Generous Car Parking
)
[images] => Array
(
[0] => Array
(
[url] => https://example.com/image1.jpg
)
[1] => Array
(
[url] => https://example.com/image2.jpg
)
)
)
)
And the code to convert the array to XML
$xml_data = new SimpleXMLElement('<?xml version="1.0"?><root></root>');
//$data = array as shown above
array_to_xml($data, $xml_data);
The specific issue lies within this method
function array_to_xml($data, &$xml_data, $isImg = FALSE, $isFeature = FALSE) {
$i = 1;
foreach ($data as $key => $value) {
if (is_numeric($key)) {
$key = 'property'; //dealing with <0/>..<n/> issues
if($isImg){
$key = 'image';
}
if($isFeature){
$key = 'feature';
}
}
if (is_array($value)) {
if($key == 'images'){
$isImg = true;
} elseif($key == 'features'){
$isFeature = true;
}
$subnode = $xml_data->addChild($key);
if($key == 'image'){
$subnode->addAttribute('id', $i);
}
array_to_xml($value, $subnode, $isImg, $isFeature);
} else {
$xml_data->addChild("$key", htmlspecialchars("$value"));
}
$i++;
}
}
The output of the XML comes out as desired except for a few parts, specifically the nested parts like features and images.Note how each <url>
is wrapped in a <feature>
node. This should be a <image>
node instead like shown in the originally XML shown at the start of this question, in addition to the id
attributes on the image nodes as well.
(the <location>
doesn't suffer from the same problem)
<features>
<feature>Prominent Building</feature>
<feature>Great Location</feature>
<feature>Grade A Office Space</feature>
<feature>Air Conditioning</feature>
<feature>Generous Car Parking</feature>
</features>
<images>
<feature>
<url>
https://example.com/image1.jpg
</url>
</feature>
<feature>
<url>
https://example.com/image2.jpg
</url>
</feature>
</images>
If I comment out
if($isFeature){
$key = 'feature';
}
and
elseif($key == 'features'){
$isFeature = true;
}
The images then are formatted correctly
<images>
<image id="1">
<url>
https://example.com/image1.jpg
</url>
</image>
<image id="2">
<url>
https://example.com/image2.jpg
</url>
</image>
</images>
but the features are incorrect, instead they become
<features>
<property>Prominent Building</property>
<property>Great Location</property>
<property>Grade A Office Space</property>
<property>Air Conditioning</property>
<property>Generous Car Parking</property>
</features>
The <property>
nodes should be <feature>
nodes instead.
Could you help me with the array_to_xml()
method to handle these and other nested arrays correctly?
Original conversion code: https://stackoverflow.com/a/5965940/10884442