I have an XML as:
<?xml version="1.0" encoding="UTF-8"?>
<products currency="EUR">
<product id="457654754" vat="13.0">
<price gross="0.09" net="0.07"/>
<sizes>
<size id="0" name="gfdgfdgfdg" panel_name="dfgfdgfdgfd" code_producer="fgdfgfdg"
iaiext:code_external="457547547547" code="354643643643" weight="4" iaiext:weight_net="10" >
<stock id="1" quantity="333"/>
</size>
</sizes>
</product>
</products>
when I parse it as:
<?php
$xml = new XMLReader;
$xml->open('XML_URL');
while ($xml->read()) {
if ($xml->nodeType === XMLReader::ELEMENT && $xml->name == 'product')
echo $xml->getAttribute('id').'<br />';
if ($xml->nodeType === XMLReader::ELEMENT && $xml->name == 'price')
echo $xml->getAttribute('net').'<br />';
if ($xml->nodeType === XMLReader::ELEMENT && $xml->name == 'size')
echo $xml->getAttribute('iaiext:code_external').'<br />';
if ($xml->nodeType === XMLReader::ELEMENT && $xml->name == 'stock')
echo $xml->getAttribute('quantity').'<br />';
}
?>
I get the values displayed correctly.
But How can I insert them into a mysql table?
I tried it inside the same while loop and I got instead of e.g 2500 rows over 48000 rows as duplicates.
How can I achieve it?
database
CREATE TABLE `table` (
`auto_increm` int(11) NOT NULL,
`un_id` int(11) NOT NULL,
`price` decimal(15,2) NOT NULL,
`quantity` int(11) NOT NULL,
`ean` varchar(255) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3;
ALTER TABLE `table`
ADD PRIMARY KEY (`auto_increm`);
ALTER TABLE `table`
MODIFY `auto_increm` int(11) NOT NULL AUTO_INCREMENT;
COMMIT;
id attribute in php = un_id in mysql table
net attribute in php = price in mysql table
iaiext:code_external attribute in php = ean in mysql table
quantity attribute in php = quantity in mysql table.
In a flat XML I was always able to perform the insert into, such as:
<?php
$doc = new DOMDocument();
$doc->load('feed.xml');
$arrFeeds = array();
foreach ($doc->getElementsByTagName('item') as $node) {
$itemRSS = array (
'sku' => $node->getElementsByTagName('itemcode')->item(0)->nodeValue,
'stock' => $node->getElementsByTagName('stock')->item(0)->nodeValue,
'price' => $node->getElementsByTagName('price_eur')->item(0)->nodeValue
);
array_push($arrFeeds, $itemRSS);
}
$counter = 0;
foreach( $arrFeeds as $RssItem){
$sku = $RssItem["sku"];
$stock = $RssItem["stock"];
$price = $RssItem["price"];
$sql = "INSERT INTO table(sku,stock,price) VALUES ('" . $sku . "','" .
$stock . "','" . $price . "')";
$counter++;
$result = mysqli_query($conn, $sql);
}
echo $counter;
mysqli_close($conn);
?>
2
Answers
To answer my question I finally imported the XML structure via xpath
as
This is a the kind of tasks where you really want to use some sort of SQL query builder. I will post (the untested) code with the Laravel’s one. You might choose any other, or build the query manually.
So, what we do – is accumulate the data for every product in a temporary array and push it to the DB every time we meet the next product.
Note: your XML might have several
sizes
for one product. The approach below will utilize only the last one, since you don’t have tables for product sizes.