【问题标题】:Convert two txt files to single XML File将两个 txt 文件转换为单个 XML 文件
【发布时间】:2020-03-20 01:55:25
【问题描述】:

我每天收到两个文本文件。一个有车辆信息,另一个有经销商信息。我将下面的脚本取消 XMLWriter 以将它们转换为 xml。有没有办法使用一个公共节点将两个 txt 文件解析为一个 XML 文档?公共节点是 FRANCHISE_ID。

我使用以下脚本将它们转换为 xml:

<?php
$data = fopen('dealers_retail.txt', 'r');
    $xml = new XMLWriter;
    $xml->openURI('dealers_retail.xml');
    $xml->setIndent(true); // makes output cleaner
    $xml->startElement('DATA');
    $flag = true;
    while ($line = fgetcsv($data, 0, '|')) {
        if($flag) { $flag = false; continue; }
       $xml->startElement('ITEM');
       $xml->writeElement('FRANCHISE_ID', $line[0]);
       $xml->writeElement('FRANCHISE_NAME', str_replace("~", "", $line[1]));
       $xml->writeElement('FRANCHISE_ADDRESS', str_replace("~", "", $line[2]));
       $xml->writeElement('FRANCHISE_CITY', str_replace("~", "", $line[3]));
       $xml->writeElement('FRANCHISE_STATE', str_replace("~", "", $line[4]));
       $xml->writeElement('FRANCHISE_ZIP', str_replace("~", "", $line[5]));
       $xml->endElement();
    }
    $xml->endElement();
?>

哪些输出:

<DATA>
 <ITEM>
  <FRANCHISE_ID>12345</FRANCHISE_ID>
  <FRANCHISE_NAME>Mercedes-Benz of XXX</FRANCHISE_NAME>
  <FRANCHISE_ADDRESS>2915 Some Street</FRANCHISE_ADDRESS>
  <FRANCHISE_CITY>Oakland</FRANCHISE_CITY>
  <FRANCHISE_STATE>CA</FRANCHISE_STATE>
  <FRANCHISE_ZIP>94611</FRANCHISE_ZIP>
 </ITEM>
</DATA>

<?php
$data = fopen('inventory_retail.txt', 'r');
    $xml = new XMLWriter;
    $xml->openURI('inventory_retail.xml');
    $xml->setIndent(true); // makes output cleaner
    $xml->startElement('DATA');
    $flag = true;
    while ($line = fgetcsv($data, 0, '|')) {
        if($flag) { $flag = false; continue; }
       $xml->startElement('ITEM');
       $xml->writeElement('FRANCHISE_ID', $line[0]);
       $xml->writeElement('VEHICLE_VIN', str_replace("~", "", $line[1]));
       $xml->writeElement('LISTING_ID', str_replace("~", "", $line[1]));
       $xml->writeElement('LIST_PRICE', str_replace("~", "", $line[2]));
       $xml->writeElement('VEHICLE_YEAR', str_replace("~", "", $line[3]));
       $xml->writeElement('MAKE_DESC', str_replace("~", "", $line[4]));
       $xml->writeElement('MODEL_DESC', str_replace("~", "", $line[5]));
       $xml->writeElement('TRIM', str_replace("~", "", $line[6]));
       $xml->writeElement('SKU', str_replace("~", "", $line[7]));
       $xml->writeElement('BODY_TYPE', str_replace("~", "", $line[8]));
       $xml->writeElement('ADF_BODY_TYPE', str_replace("~", "", $line[8]));
       $xml->writeElement('DRIVE_TYPE', str_replace("~", "", $line[9]));
       $xml->writeElement('ENGINE_DESC', str_replace("~", "", $line[10]));
       $xml->writeElement('VEHICLE_FUEL_TYPE', str_replace("~", "", $line[11]));
       $xml->writeElement('TRANSMISSION', str_replace("~", "", $line[12]));
       $xml->writeElement('ADF_TRANSMISSION', str_replace("~", "", $line[12]));
       $xml->writeElement('MILEAGE', str_replace("~", "", $line[13]));
       $xml->writeElement('NUMBER_OF_CYLINDERS', str_replace("~", "", $line[14]));
       $xml->writeElement('NUMBER_OF_DOORS', str_replace("~", "", $line[15]));
       $xml->writeElement('COLOR_DESC', str_replace("~", "", $line[16]));
       $xml->writeElement('INTERIOR_COLOR', str_replace("~", "", $line[17]));
       $xml->writeElement('INTERIOR_TYPE', str_replace("~", "", $line[18]));
       $xml->writeElement('REFERENCE_DATE', str_replace("~", "", $line[19]));
       $xml->writeElement('OPTIONS_DESC', str_replace("~", "", $line[20]));
       $xml->writeElement('AUDIO_DESC', str_replace("~", "", $line[21]));
       $xml->writeElement('SUN_ROOF', str_replace("~", "", $line[22]));
       $xml->writeElement('ALARM_SYSTEM', str_replace("~", "", $line[23]));     
       $xml->writeElement('POWER_WINDOWS', str_replace("~", "", $line[24]));
       $xml->writeElement('POWER_LOCKS', str_replace("~", "", $line[25]));
       $xml->writeElement('AIRBAGS', str_replace("~", "", $line[26]));
       $xml->writeElement('AIR_CONDITIONING', str_replace("~", "", $line[27]));
       $xml->writeElement('CRUISE_CONTROL', str_replace("~", "", $line[28]));
       $xml->writeElement('TILT_STEERING', str_replace("~", "", $line[29]));
       $xml->writeElement('POWER_STEERING', str_replace("~", "", $line[30]));
       $xml->writeElement('POWER_SEATS', str_replace("~", "", $line[31]));
       $xml->writeElement('PROMOTIONAL_TEXT', str_replace("~", "", $line[32]));
       $xml->writeElement('OEM_CERTIFIED', str_replace("~", "", $line[33]));
       $xml->writeElement('WARRANTY_DESC', str_replace("~", "", $line[34]));
       $xml->writeElement('PHOTO_AVAILABLE_FLAG', str_replace("~", "", $line[35]));     
       $xml->writeElement('PHOTO_URL', str_replace("~", "", $line[36]));    
       $xml->writeElement('SELLER_TYPE', seller_type_cdcretail);    
       $xml->writeElement('CONDITION_RADIO', used);
       $xml->writeElement('CONDITION_CHECKBOX', used);
       $xml->writeElement('ADF_CONDITION', used);
       $xml->writeElement('USE_ACCOUNT_ADDRESS', 1);
       $xml->writeElement('COUNTRY', 'united states');
       $xml->endElement();
    }
    $xml->endElement();
?>

哪些输出:

<DATA>
  <ITEM>
    <FRANCHISE_ID>12345</FRANCHISE_ID>
    <VEHICLE_VIN>12345678901234567</VEHICLE_VIN>
    <LISTING_ID>12345678901234567</LISTING_ID>
    <LIST_PRICE>47986</LIST_PRICE>
    <VEHICLE_YEAR>2019</VEHICLE_YEAR>
    <MAKE_DESC>Mercedes-Benz</MAKE_DESC>
    <MODEL_DESC>E-Class</MODEL_DESC>
    <TRIM>E 300</TRIM>
    <SKU>9999999999</SKU>
    <BODY_TYPE>4dr Car</BODY_TYPE>
    <ADF_BODY_TYPE>4dr Car</ADF_BODY_TYPE>
    <DRIVE_TYPE>RWD</DRIVE_TYPE>
    <ENGINE_DESC>Intercooled Turbo Premium Unleaded I-4 2.0 L/121</ENGINE_DESC>
    <VEHICLE_FUEL_TYPE/>
    <TRANSMISSION>9-Speed Automatic w/OD</TRANSMISSION>
    <ADF_TRANSMISSION>9-Speed Automatic w/OD</ADF_TRANSMISSION>
    <MILEAGE>7446</MILEAGE>
    <NUMBER_OF_CYLINDERS/>
    <NUMBER_OF_DOORS>4</NUMBER_OF_DOORS>
    <COLOR_DESC>White</COLOR_DESC>
    <INTERIOR_COLOR>Black Leather</INTERIOR_COLOR>
    <INTERIOR_TYPE/>
    <REFERENCE_DATE/>
    <OPTIONS_DESC>Turbocharged, Rear Wheel Drive</OPTIONS_DESC>
    <AUDIO_DESC/>
    <SUN_ROOF/>
    <ALARM_SYSTEM/>
    <POWER_WINDOWS/>
    <POWER_LOCKS/>
    <AIRBAGS/>
    <AIR_CONDITIONING/>
    <CRUISE_CONTROL/>
    <TILT_STEERING/>
    <POWER_STEERING/>
    <POWER_SEATS/>
    <PROMOTIONAL_TEXT>PRICE REDUCED, CERTIFIED</PROMOTIONAL_TEXT>
    <OEM_CERTIFIED>0</OEM_CERTIFIED>
    <WARRANTY_DESC/>
    <PHOTO_AVAILABLE_FLAG>1</PHOTO_AVAILABLE_FLAG>
    <PHOTO_URL>http://content.jpg</PHOTO_URL>
    <SELLER_TYPE>seller_type_cdcretail</SELLER_TYPE>
    <CONDITION_RADIO>used</CONDITION_RADIO>
    <CONDITION_CHECKBOX>used</CONDITION_CHECKBOX>
    <ADF_CONDITION>used</ADF_CONDITION>
    <USE_ACCOUNT_ADDRESS>1</USE_ACCOUNT_ADDRESS>
    <COUNTRY>united states</COUNTRY>
  </ITEM>
</DATA>

我想实现如下输出:

<DATA>
  <ITEM>
    <FRANCHISE_ID>12345</FRANCHISE_ID>
    <VEHICLE_VIN>12345678901234567</VEHICLE_VIN>
    <LISTING_ID>12345678901234567</LISTING_ID>
    <LIST_PRICE>47986</LIST_PRICE>
    <VEHICLE_YEAR>2019</VEHICLE_YEAR>
    <MAKE_DESC>Mercedes-Benz</MAKE_DESC>
    <MODEL_DESC>E-Class</MODEL_DESC>
    <TRIM>E 300</TRIM>
    <SKU>9999999999</SKU>
    <BODY_TYPE>4dr Car</BODY_TYPE>
    <ADF_BODY_TYPE>4dr Car</ADF_BODY_TYPE>
    <DRIVE_TYPE>RWD</DRIVE_TYPE>
    <ENGINE_DESC>Intercooled Turbo Premium Unleaded I-4 2.0 L/121</ENGINE_DESC>
    <VEHICLE_FUEL_TYPE/>
    <TRANSMISSION>9-Speed Automatic w/OD</TRANSMISSION>
    <ADF_TRANSMISSION>9-Speed Automatic w/OD</ADF_TRANSMISSION>
    <MILEAGE>7446</MILEAGE>
    <NUMBER_OF_CYLINDERS/>
    <NUMBER_OF_DOORS>4</NUMBER_OF_DOORS>
    <COLOR_DESC>White</COLOR_DESC>
    <INTERIOR_COLOR>Black Leather</INTERIOR_COLOR>
    <INTERIOR_TYPE/>
    <REFERENCE_DATE/>
    <OPTIONS_DESC>Turbocharged, Rear Wheel Drive</OPTIONS_DESC>
    <AUDIO_DESC/>
    <SUN_ROOF/>
    <ALARM_SYSTEM/>
    <POWER_WINDOWS/>
    <POWER_LOCKS/>
    <AIRBAGS/>
    <AIR_CONDITIONING/>
    <CRUISE_CONTROL/>
    <TILT_STEERING/>
    <POWER_STEERING/>
    <POWER_SEATS/>
    <PROMOTIONAL_TEXT>PRICE REDUCED, CERTIFIED</PROMOTIONAL_TEXT>
    <OEM_CERTIFIED>0</OEM_CERTIFIED>
    <WARRANTY_DESC/>
    <PHOTO_AVAILABLE_FLAG>1</PHOTO_AVAILABLE_FLAG>
    <PHOTO_URL>http://content.jpg</PHOTO_URL>
    <SELLER_TYPE>seller_type_cdcretail</SELLER_TYPE>
    <CONDITION_RADIO>used</CONDITION_RADIO>
    <CONDITION_CHECKBOX>used</CONDITION_CHECKBOX>
    <ADF_CONDITION>used</ADF_CONDITION>
    <USE_ACCOUNT_ADDRESS>1</USE_ACCOUNT_ADDRESS>
    <COUNTRY>united states</COUNTRY>
    <FRANCHISE_NAME>Mercedes-Benz of XXX</FRANCHISE_NAME>
    <FRANCHISE_ADDRESS>2915 Some Street</FRANCHISE_ADDRESS>
    <FRANCHISE_CITY>Oakland</FRANCHISE_CITY>
    <FRANCHISE_STATE>CA</FRANCHISE_STATE>
    <FRANCHISE_ZIP>94611</FRANCHISE_ZIP>
  </ITEM>
</DATA>

我尝试了以下方法,仅将经销商数据复制到属于该经销商的第一辆车。我不知道如何将它应用于特定经销商的每辆车:

<?php

$data = fopen('usacarshopucr_used_inventory_retail.txt', 'r');
// Skip header
fgetcsv($data, 0, '|');
$xml = simplexml_load_string("<DATA />");
// Array which translates the field name to the field in the input file
$itemData = ['FRANCHISE_ID' => 0, 'VEHICLE_VIN' => 1, 'LISTING_ID' => 1,
    'LIST_PRICE' => 2, 'VEHICLE_YEAR' => 3,
    'MAKE_DESC' => 4, 'MODEL_DESC' => 5
];

while ($line = fgetcsv($data, 0, '|')) {
    $item = $xml->addChild("ITEM");
    // Copy the data from the input file to the XML
    foreach ( $itemData as $name => $itemElement )   {
        $item->addChild($name, str_replace("~", "", $line[$itemElement]));
    }
}

$data = fopen('usacarshopucr_used_dealers_retail.txt', 'r');
fgetcsv($data, 0, '|');

// You will need to add all of the fields in here, this is just to show
// how to start.  Don't add the fields with a fixed value, these are added
// in separately
$itemData = ['FRANCHISE_NAME' => 1,
    'FRANCHISE_ADDRESS' => 2, 'FRANCHISE_CITY' => 3,
    'FRANCHISE_STATE' => 4, 'FRANCHISE_ZIP' => 5
];
while ($line = fgetcsv($data, 0, '|')) {
    // Find the matching item in the existing XML for the FRANCHISE_ID
    $item = $xml->xpath('//ITEM[FRANCHISE_ID="'.$line[0].'"]')[0];
    // Copy the data from the input file to the XML
    foreach ( $itemData as $name => $itemElement )   {
        $item->addChild($name, str_replace("~", "", $line[$itemElement]));
    }

    // Add in fixed data - again finish this part off
    $item->addChild('CONDITION_RADIO', 'used');
    $item->addChild('ADF_CONDITION', 'used');
}
$xml->asXML('simple_inventory_retail-2.xml');

?>

它输出:

<?xml version="1.0"?>
<DATA>
    <ITEM>
        <FRANCHISE_ID>236057</FRANCHISE_ID>
        <VEHICLE_VIN>4JGDF6EE4GA708047</VEHICLE_VIN>
        <LISTING_ID>4JGDF6EE4GA708047</LISTING_ID>
        <LIST_PRICE>39300</LIST_PRICE>
        <VEHICLE_YEAR>2016</VEHICLE_YEAR>
        <MAKE_DESC>Mercedes-Benz</MAKE_DESC>
        <MODEL_DESC>GL</MODEL_DESC>
        <FRANCHISE_NAME>Malone's Automotive</FRANCHISE_NAME>
        <FRANCHISE_ADDRESS>1827 Lower Roswell Road</FRANCHISE_ADDRESS>
        <FRANCHISE_CITY>Marietta</FRANCHISE_CITY>
        <FRANCHISE_STATE>GA</FRANCHISE_STATE>
        <FRANCHISE_ZIP>30068</FRANCHISE_ZIP>
        <CONDITION_RADIO>used</CONDITION_RADIO>
        <ADF_CONDITION>used</ADF_CONDITION>
    </ITEM>
    <ITEM>
        <FRANCHISE_ID>236057</FRANCHISE_ID>
        <VEHICLE_VIN>WA1L2AFP5GA039814</VEHICLE_VIN>
        <LISTING_ID>WA1L2AFP5GA039814</LISTING_ID>
        <LIST_PRICE>26990</LIST_PRICE>
        <VEHICLE_YEAR>2016</VEHICLE_YEAR>
        <MAKE_DESC>Audi</MAKE_DESC>
        <MODEL_DESC>Q5</MODEL_DESC>
    </ITEM>

【问题讨论】:

    标签: php xml merge


    【解决方案1】:

    这使用 SimpleXML 来创建文件,而不是尝试合并输出,这将在一个过程中读取经销商文件,从那里创建详细信息,然后读取库存文件并将详细信息添加到...

    (更新为将经销商读取到数组中,然后将详细信息一次性写入 XML 文件)。

    $data = fopen('dealers_retail.txt', 'r');
    // Skip header
    fgetcsv($data, 0, '|');
    
    // Store dealer information
    $dealers = [];
    while ($line = fgetcsv($data, 0, '|')) {
        $dealers [$line[0]] = $line;
    }
    fclose($data);
    
    $xml = simplexml_load_string("<Data />");
    
    $data = fopen('inventory_retail.txt', 'r');
    fgetcsv($data, 0, '|');
    
    $dealerData = ['FRANCHISE_ID' => 0, 'FRANCHISE_NAME' => 1,
        'FRANCHISE_ADDRESS' => 2, 'FRANCHISE_CITY' => 3,
        'FRANCHISE_STATE' => 4, 'FRANCHISE_ZIP' => 5
    ];
    
    // You will need to add all of the fields in here, this is just to show
    // how to start.  Don't add the fields with a fixed value, these are added
    // in separately
    $itemData = ['VEHICLE_VIN' => 1, 'LISTING_ID' => 1,
        'LIST_PRICE' => 2, 'VEHICLE_YEAR' => 3,
        'MAKE_DESC' => 4, 'MODEL_DESC' => 5
    ];
    while ($line = fgetcsv($data, 0, '|')) {
        // Add in dealer data
        $item = $xml->addChild("ITEM");
        $dealer = $dealers[$line[0]];
        foreach ( $dealerData as $name => $itemElement )   {
            $item->addChild($name, str_replace("~", "", $dealer[$itemElement]));
        }
        // Copy the data from the vehicle file to the XML
        foreach ( $itemData as $name => $itemElement )   {
            $item->addChild($name, str_replace("~", "", $line[$itemElement]));
        }
    
        // Add in fixed data - again finish this part off
        $item->addChild('CONDITION_RADIO', 'used');
        $item->addChild('ADF_CONDITION', 'used');
    }
    $xml->asXML('inventory_retail.xml');
    

    生成

    <?xml version="1.0"?>
    <Data>
        <ITEM>
            <FRANCHISE_ID>12345</FRANCHISE_ID>
            <FRANCHISE_NAME>Mercedes-Benz of XXX</FRANCHISE_NAME>
            <FRANCHISE_ADDRESS>2915 Some Street</FRANCHISE_ADDRESS>
            <FRANCHISE_CITY>Oakland</FRANCHISE_CITY>
            <FRANCHISE_STATE>CA</FRANCHISE_STATE>
            <FRANCHISE_ZIP>94611</FRANCHISE_ZIP>
            <VEHICLE_VIN>12345678901234567</VEHICLE_VIN>
            <LISTING_ID>12345678901234567</LISTING_ID>
            <LIST_PRICE>47986</LIST_PRICE>
            <VEHICLE_YEAR>2019</VEHICLE_YEAR>
            <MAKE_DESC>Mercedes-Benz</MAKE_DESC>
            <MODEL_DESC>E-Class</MODEL_DESC>
            <CONDITION_RADIO>used</CONDITION_RADIO>
            <ADF_CONDITION>used</ADF_CONDITION>
        </ITEM>
        <ITEM>
            <FRANCHISE_ID>12345</FRANCHISE_ID>
            <FRANCHISE_NAME>Mercedes-Benz of XXX</FRANCHISE_NAME>
            <FRANCHISE_ADDRESS>2915 Some Street</FRANCHISE_ADDRESS>
            <FRANCHISE_CITY>Oakland</FRANCHISE_CITY>
            <FRANCHISE_STATE>CA</FRANCHISE_STATE>
            <FRANCHISE_ZIP>94611</FRANCHISE_ZIP>
            <VEHICLE_VIN>12345678901234568</VEHICLE_VIN>
            <LISTING_ID>12345678901234568</LISTING_ID>
            <LIST_PRICE>47986</LIST_PRICE>
            <VEHICLE_YEAR>2019</VEHICLE_YEAR>
            <MAKE_DESC>Mercedes-Benz</MAKE_DESC>
            <MODEL_DESC>E-Class</MODEL_DESC>
            <CONDITION_RADIO>used</CONDITION_RADIO>
            <ADF_CONDITION>used</ADF_CONDITION>
        </ITEM>
    </Data>
    

    【讨论】:

    • 嗨,有没有办法在每个相应的库存项目中发布经销商数据?当前,数据仅复制到第一个 ITEM。
    【解决方案2】:

    我建议先将 CSV 文件导入数据库。如果您没有数据库服务器,请使用 SQLite。您可能可以为此使用一些 CLI 工具。在 PHP 脚本中,您可以收集多个数据项并一次插入它们以平衡内存和 CPU 使用率。

    拥有数据库后,您可以轻松地使用 JOIN 来获取聚合结果并使用 XMLWriter 输出 XML。

    此外,您还可以生成过滤或有限的结果。

    【讨论】:

    • 您好,这样可以将经销商数据复制到每辆车吗?
    • SQL 允许连接表以产生结果:SELECT * FROM listings, franchises WHERE franchises.franchise_id = listings.franchise_id
    • 您好,谢谢您的帮助。
    【解决方案3】:

    是的,您可以将 2 个传入文件中的 2 个数组合并为一个,然后才创建 xml 文件。

    $flag = true;
    
    $mergedArray = [];  // this array will contain all data
    // insert data from first file
    while ($line = fgetcsv($data_from_first_file, 0, '|')) {
        if($flag) { $flag = false; continue; }
         $mergedArray[$line[0]]['FRANCHISE_ID'] = $line[0];
         // and so on ...
    
    }
    // insert data from second file
    $flag = true;
    
    while ($line = fgetcsv($data_from_second_file, 0, '|')) {
        if($flag) { $flag = false; continue; }
         $mergedArray[$line[0]]['VEHICLE_VIN'] =  str_replace("~", "", $line[1]);
         // and so on ...
    
    }
    // now just foreach over the array to create the XML
    // ...
    $xml = new XMLWriter;
    $xml->openURI('dealers_retail.xml');
    $xml->setIndent(true);
    $xml->startElement('DATA');
    
    foreach($mergedArray as $item=>$data){
        $xml->startElement('ITEM');
        foreach($data as $index=>$value){
           $xml->writeElement($index, $value);
        }
       $xml->endElement();
    }
    $xml->endElement();
    

    【讨论】:

    • 您好,感谢您的帮助。这会为每个经销商创建一个 xml 文件,并包含一辆车。在 txt 文件中,有 141 个经销商和 140,000 辆汽车。我试图操纵它以在 xml 文件中显示每辆车,但也包括车辆 中的经销商信息
    猜你喜欢
    • 1970-01-01
    • 2018-11-05
    • 2017-06-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-11-14
    • 2015-04-12
    • 1970-01-01
    相关资源
    最近更新 更多