Insert data from XML file into MySql DB

Hi

I need to insert the data from an XML feed into a MySQL database. I have been working with simple XML to try to make this work.

<?php
class XMLParser{
    private $xml;
    public function __construct($xmlFile='default_xml_file.xml'){
        if(!file_exists($xmlFile)){
            throw new Exception('Invalid XML file.');
        }
        // read XML file
        if(!$this->xml=simplexml_load_file($xmlFile)){
            throw new Exception('Error reading XML file.');
        }
    }
    
  
    public function fetchNodesAsObjects(){
        $nodes=array();
        foreach($this->xml as $node){
            $nodes[]=$node;
        }
        return $nodes;
    }
     
}

try{
    
    $xmlPar=new XMLParser('test.xml');
    
    
    
   
    $nodes=$xmlPar->fetchNodesAsObjects();
    
    
echo "<pre>";
print_r($nodes); // ECHOS OUT THE ARRAY TREE PERFECTLY
echo "</pre>";

}
catch(Exception $e){
    echo $e->getMessage();
    exit();
}
 
?>

Resulting Array:


Array
(
    [0] => SimpleXMLElement Object
        (
            [feed_version] => 2
        )

    [1] => SimpleXMLElement Object
        (
            [id] => 179
            [name] => Test
            [email] => info@test.com
            [tel] => SimpleXMLElement Object
                (
                )

            [mob] => SimpleXMLElement Object
                (
                )

            [addr1] => SimpleXMLElement Object
                (
                )

            [addr2] => SimpleXMLElement Object
                (
                )

            [town] => SimpleXMLElement Object
                (
                )

            [region] => SimpleXMLElement Object
                (
                )

            [postcode] => SimpleXMLElement Object
                (
                )

            [country] => SimpleXMLElement Object
                (
                )

            [logo] => SimpleXMLElement Object
                (
                )

        )

    [2] => SimpleXMLElement Object
        (
            [id] => 34935
            [date] => 2009-11-03 06:52:45
            [ref] => ABC0108
            [price] => 450000
            [currency] => EUR
            [price_freq] => sale
            [part_ownership] => 0
            [leasehold] => 0
            [type] => SimpleXMLElement Object
                (
                    [en] => Plot
                )

            [town] => Cardiff
            [province] => Wales
            [location_detail] => SimpleXMLElement Object
                (
                )

            [beds] => 0
            [baths] => 0
            [pool] => 0
             => SimpleXMLElement Object
                (
                )

            [desc] => SimpleXMLElement Object
                (
                    [en] => 
Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diem nonummy nibh euismod tincidunt ut lacreet dolore magna aliguam erat volutpat. Ut wisis enim ad minim veniam, quis nostrud exerci tution ullam corper suscipit lobortis nisi ut aliquip ex ea commodo consequat. Duis te feugi facilisi. Duis autem dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit au gue duis dolore te feugat nulla facilisi.
                )

        )

    [3] => SimpleXMLElement Object
        (
            [id] => 34999
            [date] => 2009-11-10 06:52:45
            [ref] => ABC2345
            [price] => 250000
            [currency] => EUR
            [price_freq] => sale
            [part_ownership] => 0
            [leasehold] => 0
            [type] => SimpleXMLElement Object
                (
                    [en] => Plot
                )

            [town] => Ffestiniog
            [province] => Wales
            [location_detail] => SimpleXMLElement Object
                (
                )

            [beds] => 0
            [baths] => 0
            [pool] => 0
             => SimpleXMLElement Object
                (
                )

            [desc] => SimpleXMLElement Object
                (
                    [en] => 
Lorem ipsum 2 dolor sit amet, consectetuer adipiscing elit, sed diem nonummy nibh euismod tincidunt ut lacreet dolore magna aliguam erat volutpat. Ut wisis enim ad minim veniam, quis nostrud exerci tution ullam corper suscipit lobortis nisi ut aliquip ex ea commodo consequat. Duis te feugi facilisi. Duis autem dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit au gue duis dolore te feugat nulla facilisi.
                )

        )

)

The structure of the array can be seen above but I cannot seem to be able to “get at” the values to add to a query.

I have been at this for a while so the obvious is doubtless staring me in the face.

TIO

C

Can you post a sample of the XML feed?

Hi Anthony
Thanks for looking at this.

This is a local file I am using for test purposes, the feed from the URL has around 200 properties, but the structure is the same.

<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<root>
<feed>
<feed_version>2</feed_version>
</feed>
<agent>
<id>179</id>
<name>Test</name>
<email>info@test.com</email>
<tel/>
<mob/>
<addr1/>
<addr2/>

<town/>
<region/>
<postcode/>
<country/>
<logo/>
</agent>

<property>
<id>34935</id>
<date>2009-11-03 06:52:45</date>
<ref>ABC0108</ref>
<price>450000</price>
<currency>EUR</currency>
<price_freq>sale</price_freq>

<part_ownership>0</part_ownership>
<leasehold>0</leasehold>
<type>
<en>Plot</en>
</type>
<town>Cardiff</town>
<province>Wales</province>
<location_detail></location_detail>
<beds>0</beds>
<baths>0</baths>

<pool>0</pool>
<url></url>
<desc>
<en>
Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diem nonummy nibh euismod tincidunt ut lacreet dolore magna aliguam erat volutpat. Ut wisis enim ad minim veniam, quis nostrud exerci tution ullam corper suscipit lobortis nisi ut aliquip ex ea commodo consequat. Duis te feugi facilisi. Duis autem dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit au gue duis dolore te feugat nulla facilisi.</en>

</desc>
</property>

<property>
<id>34999</id>
<date>2009-11-10 06:52:45</date>
<ref>ABC2345</ref>
<price>250000</price>
<currency>EUR</currency>
<price_freq>sale</price_freq>

<part_ownership>0</part_ownership>
<leasehold>0</leasehold>
<type>
<en>Plot</en>
</type>
<town>Ffestiniog</town>
<province>Wales</province>
<location_detail></location_detail>
<beds>0</beds>
<baths>0</baths>

<pool>0</pool>
<url></url>
<desc>
<en>
Lorem ipsum 2 dolor sit amet, consectetuer adipiscing elit, sed diem nonummy nibh euismod tincidunt ut lacreet dolore magna aliguam erat volutpat. Ut wisis enim ad minim veniam, quis nostrud exerci tution ullam corper suscipit lobortis nisi ut aliquip ex ea commodo consequat. Duis te feugi facilisi. Duis autem dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit au gue duis dolore te feugat nulla facilisi.</en>

</desc>
</property>
</root>

Thanks

Colin

Try something like this Colin, it should be fairly obvious where to change/add to suit.


&lt;?php
try{
  $feed = new SimpleXMLElement('file.xml', null, true);
}catch(Exception $e){
  echo $e-&gt;getMessage();
  exit;
}

$sql = 'INSERT INTO table (`id`, `date`, `ref`, `price`) VALUES ';

foreach($feed-&gt;property as $property){
  $sql .= sprintf(
    "\
(%d, '%s', '%s', %d),",
    $property-&gt;id,
    mysql_real_escape_string($property-&gt;date),
    mysql_real_escape_string($property-&gt;ref),
    $property-&gt;price,
  );
}

$sql = rtrim($sql, ',') . ';';

echo $sql;

/*
  INSERT INTO table (`id`, `date`, `ref`, `price`) VALUES
  (34996, '2009-11-10 06:52:45', 'ABC12345', 249999),
  (34997, '2009-11-10 06:52:45', 'ABC12346', 249999),
  (34998, '2009-11-10 06:52:45', 'ABC12347', 249999),
  (34999, '2009-11-10 06:52:45', 'ABC12348', 249999);
*/
?&gt;

Excellent. Removed surplus comma from last line below, you were just testing me I guess :slight_smile:

foreach($feed->property as $property){
  $sql .= sprintf(
    "\
(%d, '%s', '%s', %d),",
    $property->id,
    mysql_real_escape_string($property->date),
    mysql_real_escape_string($property->ref),
    $property->price //removed added comma
  );

Works a treat. Thanks so much Anthony you got my vote http://www.sitepoint.com/forums/showthread.php?t=707086

Ha, er, testing… yeah, you got me. :stuck_out_tongue:

Oooo cool, thanks!

OK so I celebrated too soon. It will not insert into my DB. If I run the echoed query in PHP MyAdmin it works fine. I have also run a simplified insert using the same DB connection etc and it also works fine. ???

I am here with this:

&lt;html&gt;
&lt;head&gt;
&lt;title&gt;Insert Record&lt;/title&gt;
&lt;/head&gt;
&lt;body&gt;


&lt;?php
ini_set('display_errors', 1);
ini_set('log_errors', 1);
ini_set('error_log', dirname(__FILE__) . '/error_log.txt');
error_reporting(E_ALL);

include ('classes/xmlParser.php');

include ('conn.php');



try{
  $feed = new SimpleXMLElement('property.xml', null, true);
}catch(Exception $e){
  echo $e-&gt;getMessage();
  exit;
}

$sql = 'INSERT INTO property (`id`, `date`, `ref`, `price`) VALUES ';

foreach($feed-&gt;property as $property){
  $sql .= sprintf(
    "\
(%d, '%s', '%s', %d),",
    $property-&gt;id,
    mysql_real_escape_string($property-&gt;date),
    mysql_real_escape_string($property-&gt;ref),
    $property-&gt;price
  ) or die("Insert Error: ".mysql_error());
}

$sql = rtrim($sql, ',') . ';';

echo $sql;
?&gt;



&lt;/body&gt;
&lt;/html&gt;

No errors it just does not work?

Regards

Colin

Fixed for you, you weren’t executing the query.

:slight_smile:


&lt;html&gt;
&lt;head&gt;
&lt;title&gt;Insert Record&lt;/title&gt;
&lt;/head&gt;
&lt;body&gt;
&lt;?php

ini_set('display_errors', 1);
ini_set('log_errors', 1);
ini_set('error_log', dirname(__FILE__) . '/error_log.txt');
error_reporting(-1);

include ('conn.php');

try{
  $feed = new SimpleXMLElement('property.xml', null, true);
}catch(Exception $e){
  echo $e-&gt;getMessage();
  exit;
}

$sql = 'INSERT INTO property (`id`, `date`, `ref`, `price`) VALUES ';

foreach($feed-&gt;property as $property){
  $sql .= sprintf(
    "\
(%d, '%s', '%s', %d),",
    $property-&gt;id,
    mysql_real_escape_string($property-&gt;date),
    mysql_real_escape_string($property-&gt;ref),
    $property-&gt;price
  );
}

$sql = rtrim($sql, ',') . ';';

if(!mysql_query($sql)){
  echo '&lt;h1 style="color: red;"&gt;Error&lt;/h1&gt;&lt;p&gt;', mysql_error(), '&lt;/p&gt;';
}

?&gt;
&lt;/body&gt;
&lt;/html&gt;

Hi Anthony

All working now. The only difference I can see is this:

if(!mysql_query($sql)){
  echo '<h1 style="color: red;">Error</h1><p>', mysql_error(), '<p>';
}

Not sure why this has made the difference??

Regards

Colin

Hi all

OK so now I am very close :slight_smile: It would appear that I have some rogue characters in my feed that causes the insert to fail:

You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'Beatriz

The property
Am I correct in thinking that the

is causing the failure.

Code now:

&lt;html&gt;
&lt;head&gt;
&lt;title&gt;Insert Record&lt;/title&gt;
&lt;/head&gt;
&lt;body&gt;
&lt;?php

ini_set('display_errors', 1);
ini_set('log_errors', 1);
ini_set('error_log', dirname(__FILE__) . '/error_log.txt');
error_reporting(-1);

include ('conn.php'); // Database connection AND URL for feed



try{
  $feed = new SimpleXMLElement($xml, null, true);
}catch(Exception $e){
  echo $e-&gt;getMessage();
  exit;
}

$sql = 'INSERT INTO property (`id`, `date`, `ref`, `price`, `currency`, `price_freq`, `part_ownership`, `leasehold`, `type`, `country`, `town`, `province`, `beds`, `baths`, `pool`, `desc`) VALUES ';

foreach($feed-&gt;property as $property){
  $sql .= sprintf(
    //"\
(%d, '%s', '%s', %d),",
    "\
(%d, '%s', '%s', '%d', '%s', '%s', '%d', '%d', '%s', '%s', '%s', '%s', '%d', '%d', '%d', %s),",
   $property-&gt;id,
   mysql_real_escape_string($property-&gt;date),
   mysql_real_escape_string($property-&gt;ref),
   $property-&gt;price,
   mysql_real_escape_string($property-&gt;currency),
   mysql_real_escape_string($property-&gt;price_freq),
   $property-&gt;part_ownership,
   $property-&gt;leasehold,
   mysql_real_escape_string($property-&gt;type-&gt;en),
   mysql_real_escape_string($property-&gt;country),
   mysql_real_escape_string($property-&gt;town),
   mysql_real_escape_string($property-&gt;province),
   $property-&gt;beds,
   $property-&gt;baths,
   $property-&gt;pool,
   mysql_real_escape_string($property-&gt;desc-&gt;en)
  );
}

$sql = rtrim($sql, ',') . ';';

echo $sql;

if(!mysql_query($sql)){
  echo '&lt;h1 style="color: red;"&gt;Error&lt;/h1&gt;&lt;p&gt;', mysql_error(), '&lt;p&gt;';
}
else
{
echo "Records have been inserted into the database";
}
?&gt;
&lt;/body&gt;
&lt;/html&gt;
INSERT INTO property (`id`, `date`, `ref`, `price`, `currency`,  `price_freq`, `part_ownership`, `leasehold`, `type`, `country`, `town`,  `province`, `beds`, `baths`, `pool`, `desc`) VALUES  (34935, '2009-11-03 06:52:45', 'SVS0108', '450000', 'EUR', 'sale', '0',  '0', 'Plot', 'Spain', 'Estepona', 'Malaga', '0', '0', '0', Camino  Beatriz\
\
The property is

Colin

OK Problem resolved here:

'%s'),",

Missed the commas

C