显示 2 个 xml 文件之间的差异(使用 php) [英] Show the differences between 2 xml files (with php)

查看:20
本文介绍了显示 2 个 xml 文件之间的差异(使用 php)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个具有以下结构的 xml 文件.

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>

xml 文件有大约 1000 个产品.

The xml file has about 1000 products.

我想要实现的是,当我下载一个新的 xml PHP 代码时,应该检查哪些产品已经改变了股票价格的值.

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.

我有一个数组递归方法,它显示了 xml 文件之间的差异.但它只显示 xml 节点,即如果股票已更改,我只能看到数组中的股票.

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;
}

谁能帮我不仅显示xml的差异字段,还显示已更改的整个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.

先谢谢大家.

推荐答案

下面的代码将

  • 查找并显示产品元素的outerXML
  • 具有相同的 product_id
  • 但价格或库存有所不同.

它的工作原理是迭代旧 XML 中的所有产品元素,收集它们的 product_id、价格和库存值,并将它们组合成一个 XPath 查询,然后针对新文档运行.

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.

$oldXml = new DOMDocument;
$oldXml->loadXml($old);
$query = array();
foreach ($oldXml->getElementsByTagName('product') as $product) {
    $query[] = sprintf(
        '(product_id = %s and (price != "%s" or stock != "%s"))',
        $product->getElementsByTagName('product_id')->item(0)->nodeValue,
        $product->getElementsByTagName('price')->item(0)->nodeValue,
        $product->getElementsByTagName('stock')->item(0)->nodeValue
    );
}
$query = implode('or', $query);

$newXml = new DOMDocument;
$newXml->loadXml($new);
$xp = new DOMXPath($newXml);
foreach ($xp->query(sprintf('/products/product[%s]', $query)) as $product) {
    echo $newXml->saveXml($product);
}

使用 SimpleXml

$oldXml = simplexml_load_string($old);
$query = array();
foreach ($oldXml->product as $product) {
    $query[] = sprintf(
        '(product_id = %s and (price != "%s" or stock != "%s"))',
        $product->product_id,
        $product->price,
        $product->stock
    );
}
$query = implode('or', $query);

$newXml = simplexml_load_string($new);
foreach ($newXml->xpath(sprintf('/products/product[%s]', $query)) as $product) {
    echo $product->asXml();
}

请注意,这不会在新文档中找到任何已添加或删除的产品元素.你没有在你的问题中提到这是一项要求.如果您也需要这个,最简单的方法是为此编写两个额外的查询.一种是将旧文档中的 product_id 元素与新文档进行比较,另一种是将新文档中的 product_id 元素与旧文档进行比较.

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.

这篇关于显示 2 个 xml 文件之间的差异(使用 php)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆