I know duplicate keys in array is not possible. There is an API that i send data to in XML format. The prosess is that i need to hold it in Array before i convert it to XML and send it to the API. The API only accepts the format i show you under. So this is my problem i need help with:
XML format API need (Preferred result):
<root>
<id>FACE</id>
<title>FACEBOOK NOVEMBER 2019</title>
<agreement_id>REDP</agreement_id>
<contact>Sidra</contact>
<order_id>4715</order_id>
<plan_no>417</plan_no>
<insertion>
<insertion_date>2019-10-08</insertion_date>
<start_date>2019-10-08</start_date>
<end_date>2019-10-09</end_date>
<PO_number>150</PO_number>
<price_row>
<price_code>000</price_code>
<gross>11111</gross>
</price_row>
</insertion>
<insertion>
<insertion_date>2019-10-09</insertion_date>
<start_date>2019-10-09</start_date>
<end_date>2019-10-10</end_date>
<PO_number>152</PO_number>
<price_row>
<price_code>000</price_code>
<gross>11111</gross>
</price_row>
</insertion>
<type>method_name</type>
<password>*******</password>
<company_id>*******</company_id>
</root>
This i cannot find a solution for when having an Array
, because the insertion
block need to be identical like this.
Here is my solution for my request from converting multidimensional array to XML format:
static function addXMLData(\SimpleXMLElement $xml, array $data) {
array_walk($data, function ($value, $key) use ($xml) {
if (is_array($value)) {
$child = $xml->addChild($key);
self::addXMLData($child, $value);
} else {
$xml->addChild($key, $value);
}
});
}
static function createXML($data, $root = null) {
$xml = new \SimpleXMLElement($root ? '<' . $root . '/>' : '<root/>');
self::addXMLData($xml, $data);
$dom = dom_import_simplexml($xml)->ownerDocument;
$dom->encoding = "UTF-8";
$dom->formatOutput = true;
echo $dom->saveXML();
}
This is the array i send in from client:
$order_data = array([
"id" => 'FACE',
"title" => 'FACEBOOK NOVEMBER 2019',
"agreement_id" => 'REDP',
"contact" => "Sidra",
"order_id" => 4715,
"plan_no" => 417,
"insertion" => [
"insertion_date" => '2019-10-08',
"start_date" => '2019-10-08',
"end_date" => "2019-10-09",
"PO_number" => 150,
"price_row" => [
"price_code" => '000',
"gross" => 11111
],
],
"insertion" => [
"insertion_date" => '2019-10-09',
"start_date" => '2019-10-09',
"end_date" => "2019-10-10",
"PO_number" => 151,
"price_row" => [
"price_code" => '000',
"gross" => 11111
],
]
]);
echo "<pre>";
print_r($order_data);
die;
This result removes the duplicate array key and it will not work. How can i smart convert this to XML and keep the duplicate keys?
This is my complete function, sorry for a lot of code. $data_flatten
is the array above. _request
has the CreateXML
method inside. Ive hardcoded the insertion
"bulk"
public function create_order_direct($order_data) {
$data_flatten = [];
array_walk_recursive($order_data, function ($v, $k) use (&$data_flatten) {
$data_flatten[$k] = $v;
});
// If present = replace
// Else create new order with entries(insertion)
if (!isset($data_flatten['order_id'])) {
$data_flatten['order_id'] = "";
}
return $this->__request(__FUNCTION__, [
"id" => $data_flatten['media_id'],
"title" => $data_flatten['headline'],
"agreement_id" => self::AGREEMENT_ID,
"contact" => $data_flatten['client_contact'],
"order_id" => $data_flatten['order_id'],
"plan_no" => $data_flatten['plan_number'],
"insertion" => [
"insertion_date" => '2019-10-08',
"start_date" => '2019-10-08',
"end_date" => "2019-10-09",
"PO_number" => 150,
"price_row" => [
"price_code" => '000',
"gross" => 11111
]
],
"insertions" => [
[
"insertion_date" => '2019-10-09',
"start_date" => '2019-10-09',
"end_date" => "2019-10-10",
"PO_number" => 152,
"price_row" => [
"price_code" => '000',
"gross" => 11111
],
]
]);
}
EDIT / UPDATE:
Thank you guys. I followed your advice and now added array inside an array for insertion
block as you suggested. The result i have now looks like this:
<root>
<id>FACE</id>
<title>FACEBOOK NOVEMBER 2019</title>
<agreement_id>REDP</agreement_id>
<contact>Sidra</contact>
<order_id>4715</order_id>
<plan_no>417</plan_number>
<insertion>
<0>
<insertion_date>2019-10-08</insertion_date>
<start_date>2019-10-08</start_date>
<end_date>2019-10-09</end_date>
<PO_number>150</PO_number>
<price_row>
<price_code>000</price_code>
<gross>11111</gross>
</price_row>
</0>
<1>
<insertion_date>2019-10-09</insertion_date>
<start_date>2019-10-09</start_date>
<end_date>2019-10-10</end_date>
<PO_number>151</PO_number>
<price_row>
<price_code>000</price_code>
<gross>11111</gross>
</price_row>
</1>
</insertion>
<type>method_name</type>
<password>********</password>
</marathon>
The only problem i see now is that the XML add numbers for the multidimensional array. And i need to wrap multiple <insertion>
block where the numeric key starts. How can i do that?
This is what i want:
<root>
<id>FACE</id>
<title>FACEBOOK NOVEMBER 2019</title>
<agreement_id>REDP</agreement_id>
<contact>Sidra</contact>
<order_id>4715</order_id>
<plan_no>417</plan_number>
<insertion>
<insertion_date>2019-10-08</insertion_date>
<start_date>2019-10-08</start_date>
<end_date>2019-10-09</end_date>
<PO_number>150</PO_number>
<price_row>
<price_code>000</price_code>
<gross>11111</gross>
</price_row>
</insertion>
<insertion>
<insertion_date>2019-10-09</insertion_date>
<start_date>2019-10-09</start_date>
<end_date>2019-10-10</end_date>
<PO_number>151</PO_number>
<price_row>
<price_code>000</price_code>
<gross>11111</gross>
</price_row>
</insertion>
<type>method_name</type>
<password>********</password>
</marathon>