i have an xml file with the following structure.
<?xml version="1.0" encoding="utf-8"?>
<products>
<product>
<nr>0</nr>
<product_id>17856</product_id>
<product_number>54586</product_number>
<product_name>just an name</product_name>
<product_url>product url</product_url>
<price>66.3445</price>
<description> bla die bla </description>
<manufacturer>manu 1</manufacturer>
<category>category 1</category>
<stock>3</stock>
<eancode></eancode>
<date_added>2011-04-18 12:10:28</date_added>
<image_front></image_front>
<image_back></image_back>
<vat_value>1.19</vat_value>
</product>
</products>
The xml file has about 1000 products.
What i would like to achieve is that when i download an new xml PHP code should check which products have changed values of the price an stock.
I have an array recursive method which show the differences between the xml files. But it only shows the xml nodes, i.e. if the stock have been changed i only see the stock in the array.
i use the following function to show the differences.
public function checkFile($file){
$xml = simplexml_load_file("./var/import/".$file); //nieuw
$xml1 = $this->simplexml2array($xml);
$xmls = simplexml_load_file("./var/import/oud/".$file); //oud
$xml2 =$this->simplexml2array($xmls);
$checkdiff = $this->arrayRecursiveDiff($xml2, $xml1);
if ($checkdiff == NULL){
return false;
}else{
return true;
}
}
public function arrayRecursiveDiff($aArray1, $aArray2) {
$aReturn = array();
foreach ($aArray1 as $mKey => $mValue) {
if (array_key_exists($mKey, $aArray2)) {
if (is_array($mValue)) {
$aRecursiveDiff = $this->arrayRecursiveDiff($mValue, $aArray2[$mKey]);
if (count($aRecursiveDiff)) { $aReturn[$mKey] = $aRecursiveDiff; }
} else {
if ($mValue != $aArray2[$mKey]) {
$aReturn[$mKey] = $mValue;
}
}
} else {
$aReturn[$mKey] = $mValue;
}
}
return $aReturn;
}
function simplexml2array($xml) {
if (get_class($xml) == 'SimpleXMLElement') {
$attributes = $xml->attributes();
foreach($attributes as $k=>$v) {
if ($v) $a[$k] = (string) $v;
}
$x = $xml;
$xml = get_object_vars($xml);
}
if (is_array($xml)) {
if (count($xml) == 0) return (string) $x; // for CDATA
foreach($xml as $key=>$value) {
$r[$key] = $this->simplexml2array($value);
}
if (isset($a)) $r['@attributes'] = $a; // Attributes
return $r;
}
return (string) $xml;
}
can anybody help me not to only show the the difference field of the xml but the whole xml product information which have been changed.
thank you all in advance.
The following code will
It works by iterating all product elements in the old XML, collecting their product_id, price and stock values and assemble them into an XPath query that is then run against the new document.
With DOM
With SimpleXml
Note that this will not find any product elements that have been added or removed in the new document. You didnt mention that as a requirement in your question. If you need this as well, the easiest would be to write two additional queries for that. One comparing the product_id elements from the old document with the new doc and one doing the same from the new doc to the old.
Try this diff algorithm:
https://github.com/paulgb/simplediff/blob/5bfe1d2a8f967c7901ace50f04ac2d9308ed3169/simplediff.php