XML omzetten naar CSV verdwijnt de header soms
Nu kom ik er niet meer uit.
Deze functie gebruik ik om een xml bestand om te zetten naar csv
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
function convertXmlToCsvFile($xml_file_input, $csv_file_output) {
$xml = simplexml_load_file($xml_file_input);
$output_file = fopen($csv_file_output, 'w');
$header = false;
foreach($xml as $key => $value){
if(!$header) {
fputcsv($output_file, array_keys(get_object_vars($value),',','"'));
$header = true;
}
fputcsv($output_file, get_object_vars($value),',','"');
}
fclose($output_file);
}
$doen = convertXmlToCsvFile(DOC_ROOT.'shopconnector/feeds/feed'.$_POST['id'].'import.xml',DOC_ROOT.'shopconnector/feeds/feed'.$_POST['id'].'import.csv');
$xml = simplexml_load_file($xml_file_input);
$output_file = fopen($csv_file_output, 'w');
$header = false;
foreach($xml as $key => $value){
if(!$header) {
fputcsv($output_file, array_keys(get_object_vars($value),',','"'));
$header = true;
}
fputcsv($output_file, get_object_vars($value),',','"');
}
fclose($output_file);
}
$doen = convertXmlToCsvFile(DOC_ROOT.'shopconnector/feeds/feed'.$_POST['id'].'import.xml',DOC_ROOT.'shopconnector/feeds/feed'.$_POST['id'].'import.csv');
Een xml die wel met de headers (veldnamen) in de xml als eerste regel word opgeslagen is bij deze wel goed:
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
<?xml version="1.0" encoding="utf-8"?>
<Products>
<Product>
<Product_ID>LI64MB520</Product_ID>
<Product_Name>Siemens iQ100 LI64MB520 Vlakscherm-afzuigkappen - Zilver</Product_Name>
<Product_URL>https://prf.hn/click/camref:1011l3rad/creativeref:1100l6935/destination:https://www.ao.nl/product/li64mb520-siemens-vlakscherm-afzuigkappen-zilver-39457-4.aspx?&WT.z_PT=MDA&WT.z_AT=Afzuigkappen&WT.z_BR=Siemens&WT.z_FT=Built%20In&WT.z_PC=LI64MB520_GY&WT.z_MT=Affiliate&WT.z_RTM=PHG&WT.srch=1</Product_URL>
<Image_Thumbnail_URL>http://media.ao.com/productafbeeldingen/klein/li64mb520_gy_siemens_afzuigkap_fr_s.jpg</Image_Thumbnail_URL>
<Image_Medium_URL>http://media.ao.com/productafbeeldingen/medium/li64mb520_gy_siemens_afzuigkap_fr_m_p.jpg</Image_Medium_URL>
<Image_Large_URL>http://media.ao.com/productafbeeldingen/groot/li64mb520_gy_siemens_afzuigkap_fr_l.jpg</Image_Large_URL>
<Price>248.00</Price>
<Description>Siemens iQ100 LI64MB520 Vlakscherm-afzuigkappen - Zilver</Description>
<Product_Category>Home & Garden > Kitchen & Dining > Kitchen Appliances > Range Hoods</Product_Category>
<Product_Type>Afzuigkappen</Product_Type>
<Category />
<Sub_Category />
<SKU>LI64MB520</SKU>
<Promo_Text />
<Previous_Price />
<Warranty>2 Jaren</Warranty>
<Brand>Siemens</Brand>
<Availability>In voorraad</Availability>
<Condition>Neu</Condition>
<Colour>Zilver</Colour>
<EAN_Code>4242003717851</EAN_Code>
<Height>175</Height>
<Width>598</Width>
<Depth>290</Depth>
<Delivery_Cost>0.0000</Delivery_Cost>
<Company_URL>https://prf.hn/click/camref:1011l3rad/creativeref:1100l6935/destination:http://www.ao.nl</Company_URL>
<Delivery_Time>2 Werkdagen</Delivery_Time>
<Energy_Efficiency_Class>B</Energy_Efficiency_Class>
<Promotions />
<Manufacturer>BSH</Manufacturer>
<GTIN_Code>4242003717851</GTIN_Code>
<Fit_Type>Ingebouwd</Fit_Type>
<Country>DEU</Country>
<Additional_ProductInformation />
<Payment_Method>Maestro Visa - Visa Debit Mastercard Paypal</Payment_Method>
<Dimensions>(H)17,5 x (B)59,8 x (T)29,0</Dimensions>
<InStock>True</InStock>
</Product>
<Products>
<Product>
<Product_ID>LI64MB520</Product_ID>
<Product_Name>Siemens iQ100 LI64MB520 Vlakscherm-afzuigkappen - Zilver</Product_Name>
<Product_URL>https://prf.hn/click/camref:1011l3rad/creativeref:1100l6935/destination:https://www.ao.nl/product/li64mb520-siemens-vlakscherm-afzuigkappen-zilver-39457-4.aspx?&WT.z_PT=MDA&WT.z_AT=Afzuigkappen&WT.z_BR=Siemens&WT.z_FT=Built%20In&WT.z_PC=LI64MB520_GY&WT.z_MT=Affiliate&WT.z_RTM=PHG&WT.srch=1</Product_URL>
<Image_Thumbnail_URL>http://media.ao.com/productafbeeldingen/klein/li64mb520_gy_siemens_afzuigkap_fr_s.jpg</Image_Thumbnail_URL>
<Image_Medium_URL>http://media.ao.com/productafbeeldingen/medium/li64mb520_gy_siemens_afzuigkap_fr_m_p.jpg</Image_Medium_URL>
<Image_Large_URL>http://media.ao.com/productafbeeldingen/groot/li64mb520_gy_siemens_afzuigkap_fr_l.jpg</Image_Large_URL>
<Price>248.00</Price>
<Description>Siemens iQ100 LI64MB520 Vlakscherm-afzuigkappen - Zilver</Description>
<Product_Category>Home & Garden > Kitchen & Dining > Kitchen Appliances > Range Hoods</Product_Category>
<Product_Type>Afzuigkappen</Product_Type>
<Category />
<Sub_Category />
<SKU>LI64MB520</SKU>
<Promo_Text />
<Previous_Price />
<Warranty>2 Jaren</Warranty>
<Brand>Siemens</Brand>
<Availability>In voorraad</Availability>
<Condition>Neu</Condition>
<Colour>Zilver</Colour>
<EAN_Code>4242003717851</EAN_Code>
<Height>175</Height>
<Width>598</Width>
<Depth>290</Depth>
<Delivery_Cost>0.0000</Delivery_Cost>
<Company_URL>https://prf.hn/click/camref:1011l3rad/creativeref:1100l6935/destination:http://www.ao.nl</Company_URL>
<Delivery_Time>2 Werkdagen</Delivery_Time>
<Energy_Efficiency_Class>B</Energy_Efficiency_Class>
<Promotions />
<Manufacturer>BSH</Manufacturer>
<GTIN_Code>4242003717851</GTIN_Code>
<Fit_Type>Ingebouwd</Fit_Type>
<Country>DEU</Country>
<Additional_ProductInformation />
<Payment_Method>Maestro Visa - Visa Debit Mastercard Paypal</Payment_Method>
<Dimensions>(H)17,5 x (B)59,8 x (T)29,0</Dimensions>
<InStock>True</InStock>
</Product>
Maar bij deze niet. Bij deze zijn de headers leeg:
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<products>
<product>
<sku>122470</sku>
<upc>045496521288</upc>
<product_name>Mario Kart 7 3DS</product_name>
<brand>Nintendo</brand>
<currency>EUR</currency>
<price>42.99</price>
<condition>new</condition>
<product_url>https://prf.hn/click/camref:1100l5eGG/creativeref:1101l32317/destination:https://www.coolblue.nl/product/122470/mario-kart-7-3ds.html</product_url>
<image_url>https://image.coolblue.nl/1024x1024/products/139591.jpg</image_url>
<free_shipping>yes</free_shipping>
<category>Games</category>
<product_type>Games</product_type>
<availability>2</availability>
<shipping_cost>0.00</shipping_cost>
<group>yes</group>
<reviewsaveragescore>9.8</reviewsaveragescore>
<reviewscount>19</reviewscount>
<coolblueskeuze>0</coolblueskeuze>
<delivery_time>Voor 23.59 uur besteld, morgen in huis.</delivery_time>
<categoryid>2053</categoryid>
</product>
<product>
<sku>122470</sku>
<upc>045496521288</upc>
<product_name>Mario Kart 7 3DS</product_name>
<brand>Nintendo</brand>
<currency>EUR</currency>
<price>42.99</price>
<condition>new</condition>
<product_url>https://prf.hn/click/camref:1100l5eGG/creativeref:1101l32317/destination:https://www.coolblue.nl/product/122470/mario-kart-7-3ds.html</product_url>
<image_url>https://image.coolblue.nl/1024x1024/products/139591.jpg</image_url>
<free_shipping>yes</free_shipping>
<category>Games</category>
<product_type>Games</product_type>
<availability>2</availability>
<shipping_cost>0.00</shipping_cost>
<group>yes</group>
<reviewsaveragescore>9.8</reviewsaveragescore>
<reviewscount>19</reviewscount>
<coolblueskeuze>0</coolblueskeuze>
<delivery_time>Voor 23.59 uur besteld, morgen in huis.</delivery_time>
<categoryid>2053</categoryid>
</product>
Ik kan er dan niks mee de eerste 4 waarden zijn dan leeg ??
Hoe kan dit? en hoe is dit op te lossen?
Toevoeging op 03/04/2019 13:46:30:
De server gebruikt PHP 7
Toevoeging op 03/04/2019 13:51:55:
Met deze functie leest hij het bestand wel maar haalt alle whitespaces weg, maar laat nog teed niet de node waarden zien als header:
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
2
3
4
5
6
7
8
9
10
11
12
13
14
function convertXmlToCsvFile($xml_file_input, $csv_file_output,$innerNode) {
if (file_exists($xml_file_input)) {
$xml = simplexml_load_file($xml_file_input);
$f = fopen($csv_file_output, 'w');
foreach ($xml->{$innerNode} as $product) {
//echo $car->getName();
fputcsv($f, get_object_vars($product),',','"');
}
fclose($f);
}
}
if (file_exists($xml_file_input)) {
$xml = simplexml_load_file($xml_file_input);
$f = fopen($csv_file_output, 'w');
foreach ($xml->{$innerNode} as $product) {
//echo $car->getName();
fputcsv($f, get_object_vars($product),',','"');
}
fclose($f);
}
}
De eerste is deze leeg omdat de eerste 4 regels leeg zijn:
$data = fgetcsv($file,null , ''.$r['delimiterr'].'')
De laatste pakt hem wel, maar dan zonder headers
simple_xml_load_file() het object bouwt, en hoe get_object_vars() hier vervolgens mee omgaat?
Bekijk de verschillende objecten eens met var_dump() ofzo.
Een truuk die geloof ik ook populair is is om het object door een json_encode()/_decode() te halen. Het resultaat is een associatief array die mogelijk wat makkelijker te doorlopen is.
Ook in de user comments van get_object_vars() staan interessante dingen. De PHP-documentatie en de bijbehorende comments bevatten vaak een schat aan informatie.
Heeft dit niet gewoon te maken met hoe Bekijk de verschillende objecten eens met var_dump() ofzo.
Een truuk die geloof ik ook populair is is om het object door een json_encode()/_decode() te halen. Het resultaat is een associatief array die mogelijk wat makkelijker te doorlopen is.
Ook in de user comments van get_object_vars() staan interessante dingen. De PHP-documentatie en de bijbehorende comments bevatten vaak een schat aan informatie.
Code (php)
1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
$result = $xml->xpath("//".$waardepost."")[0];
$arr = json_decode( json_encode($result) , 1);
foreach ($arr as $key => $waarde) {
echo $key;
fputcsv($f, $key,',','"');
}
$arr = json_decode( json_encode($result) , 1);
foreach ($arr as $key => $waarde) {
echo $key;
fputcsv($f, $key,',','"');
}
De key word geprint, maar krijg hem maar niet via fputcsv in de csv, snap niet waarom
is dat wel een string?
Als niet, dan zou in plaats van $key in de fput functie misschien (string)$key gebruikt kunnen worden.
Aan de ene kant heb je het uitlezen van een XML (#1).
Aan de andere kant heb je het schrijven naar een CSV (#2).
Dit laatste zou absoluut geen probleem moeten zijn als je hiervoor een normaal associatief array gebruikt.
Dus, waar je voor zou moeten zorgen is dat #1 een fatsoenlijk associatief array uitpoept, zodat het schrijven naar CSV (#2) nooit een probleem vormt.
En wat je dus (enkel) zou moeten uitzoeken is waarom #1 niet het gewenste resultaat oplevert. Hiertoe zou je wat simplexml retourneert nader moeten inspecteren, zoals hiervoven al een aantal keer is aangehaald.
Wat je dus in wezen doet is het standaardiseren van wat je aan het CSV-deel voert, zodat het gedrag van deze data altijd voorspelbaar is (doordat het een standaard format (associatief array) heeft).
Gewijzigd op 04/04/2019 16:25:30 door Thomas van den Heuvel