XML 重复值 - PHP

XML duplicate values - PHP

晚上好!

有人可以指导我如何将具有相同值的 child 添加到一个中。我有这个 XML 文件:https://wpcoder.co.uk//links/sir_prakash_webdev1/ws7/currency.xml

如您所见,欧元货币已在许多不同的国家/地区使用,即:

<currency code="EUR">
    <ccode>EUR</ccode>
    <cname>Euro</cname>
    <cntry>CYPRUS</cntry>
    <crate>1.199119</crate>
</currency>
<currency code="EUR">
    <ccode>EUR</ccode>
    <cname>Euro</cname>
    <cntry>ANDORRA</cntry>
    <crate>1.199119</crate>
</currency>

所以我想要的是将使用相同货币(美元、欧元等)的国家添加到单个 child 即

我当前生成 XML 文档的代码是:

<?php 

$iso_curr_xml = simplexml_load_file("curr_old.xml");

$rates_json_url = file_get_contents("https://freecurrencyapi.net/api/v2/latest?apikey=4392e6c0-67d6-11ec-82cc-4d7a41b7625b&base_currency=GBP");

$rate_json_obj = json_decode($rates_json_url);

$ts = $rate_json_obj->query->timestamp;

$currencies = new SimpleXMLElement('<?xml version="1.0" encoding="utf-8"?><currencies ts="'.$ts.'" />');

foreach($iso_curr_xml as $xml_parse) {
    foreach($xml_parse as $xml_res) {
        $crcode = $xml_res->Ccy;
        $currency = $currencies->addChild('currency');
        $currency->addAttribute('code', $xml_res->Ccy);
        $currency->addChild( 'ccode', $xml_res->Ccy );
        $currency->addChild( 'cname', $xml_res->CcyNm );
        $currency->addChild( 'cntry', $xml_res->CtryNm );
        $currency->addChild( 'crate', $rate_json_obj->data->$crcode );
    }
}
$currencies->asXML("currency.xml");

抱歉,我至少知道我认为我需要 xPath,但不知道如何。谢谢!

您可以在数组中重新组合(使用相同的键),然后再写入 XML :


$iso_curr_xml = simplexml_load_file('https://wpcoder.co.uk//links/sir_prakash_webdev1/ws7/curr_old.xml');
$rates_json_url = file_get_contents('https://freecurrencyapi.net/api/v2/latest?apikey=4392e6c0-67d6-11ec-82cc-4d7a41b7625b&base_currency=GBP');

$rate_json_obj = json_decode($rates_json_url);
$ts = $rate_json_obj->query->timestamp;


// Regroup by crcode :

$codes = [];
foreach ($iso_curr_xml->CcyTbl->CcyNtry as $xml_res) {
    $crcode = (string)$xml_res->Ccy;

    // if the key doesn't exists, get shared data 
    if (!isset($codes[$crcode])) {
        $codes[$crcode]['ccode'] = (string)$xml_res->Ccy;
        $codes[$crcode]['cname'] = (string)$xml_res->CcyNm;
        $codes[$crcode]['crate'] = $rate_json_obj->data->{$crcode} ?? 0;
    }

    // in all cases, add country name
    $codes[$crcode]['cntry'][] = (string)$xml_res->CtryNm;
}

// Now, generate the XML (based on the previous array) :

$currencies = new SimpleXMLElement('<?xml version="1.0" encoding="utf-8"?><currencies ts="' . $ts . '" />');
foreach ($codes as $crcode => $data) {
    $currency = $currencies->addChild('currency');
    $currency->addAttribute('code', $crcode);
    $currency->addChild('ccode', $data['ccode']);
    $currency->addChild('cname', $data['cname']);
    $currency->addChild('cntry', implode(', ', $data['cntry'])); // implode countries
    $currency->addChild('cname', $data['crate']);
}
$currencies->asXML('currency.xml');

输出:

<?xml version="1.0" encoding="UTF-8"?>
<currencies ts="1642451660">
   <currency code="AFN">
      <ccode>AFN</ccode>
      <cname>Afghani</cname>
      <cntry>AFGHANISTAN</cntry>
      <cname>143.232437</cname>
   </currency>
   <currency code="EUR">
      <ccode>EUR</ccode>
      <cname>Euro</cname>
      <cntry>ÅLAND ISLANDS, ANDORRA, AUSTRIA, BELGIUM, CYPRUS, ESTONIA, EUROPEAN UNION, FINLAND, FRANCE, FRENCH GUIANA, FRENCH SOUTHERN TERRITORIES (THE), GERMANY, GREECE, GUADELOUPE, HOLY SEE (THE), IRELAND, ITALY, LATVIA, LITHUANIA, LUXEMBOURG, MALTA, MARTINIQUE, MAYOTTE, MONACO, MONTENEGRO, NETHERLANDS (THE), PORTUGAL, RÉUNION, SAINT BARTHÉLEMY, SAINT MARTIN (FRENCH PART), SAINT PIERRE AND MIQUELON, SAN MARINO, SLOVAKIA, SLOVENIA, SPAIN</cntry>
      <cname>1.198999</cname>
   </currency>
   <!-- ... -->
</currencies>