gpt4 book ai didi

php - 显示 2 个 xml 文件之间的差异(使用 php)

转载 作者:数据小太阳 更新时间:2023-10-29 02:32:05 24 4
gpt4 key购买 nike

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

    <?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 个产品。

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

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

我使用以下函数来显示差异。

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 产品信息。

提前谢谢大家。

最佳答案

下面的代码会

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

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

使用DOM

$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 元素与旧文档进行比较。

关于php - 显示 2 个 xml 文件之间的差异(使用 php),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6640255/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com