首页 > 解决方案 > 使用 PHP 转换器将 XML 转换为 CSV [图像抓取问题]

问题描述

我真的需要你的帮助,他们使用 XML 和 PHP。寻找了许多其他问题,但是当在 xml 中有更深的字段并且我无法将它们抓取到 csv 输出(下面的代码)时,仍然没有找到关于我的情况。

<product>
<images>
<image>...</image>
<image>...</image>
</images>
</product>

我的 XML 文件如下所示:

<root>
<product>
<url>
<![CDATA[
https://
]]>
</url>
<id>185</id>
<barcode>284</barcode>
<categories>
<category>14</category>
<category>2</category>
</categories>
<title>
<![CDATA[ Product1 ]]>
</title>
<description>
<![CDATA[
<p>description</p>
]]>
</description>
<price>10</price>
<sec_costs>13.000000</sec_costs>
<quantity>10</quantity>
<warranty/>
<weight>0.000000</weight>
<delivery_text>
<![CDATA[ 1 - 2 d. ]]>
</delivery_text>
<manufacturer>
<![CDATA[ ]]>
</manufacturer>
<images>
        <image>
<![CDATA[
https://test.eu/r.jpg
]]>
       </image>
        <image>
<![CDATA[
https://test.eu/er.jpg
]]>
       </image>
        <image>
<![CDATA[
https://test.eu/eer.jpg
]]>
       </image>
</images>
<product_with_gift>
<![CDATA[ False ]]>
</product_with_gift>
<barcode_format>
<![CDATA[ EAN ]]>
</barcode_format>
</product>

我正在使用此代码将其从 XML 转换为 CSV(从其他成员使用),问题是代码工作正常,但它不抓取图像(尝试用图像替换图像,添加额外的图像列,但没有任何效果出来,它只是不抓取图像文件的链接:

<?
$filexml = 'imp2.xml';
$xml = simplexml_load_file($filexml);
$xml->registerXPathNamespace('g', 'http://base.google.com/ns/1.0');

if (file_exists($filexml))  {    
   $xml = simplexml_load_file($filexml);
   $i = 1;           // Position counter
   $values = [];     // PHP array

   // Writing column headers
   $columns = array('id', 'barcode', 'title', 'description', 'price', 'sec_costs', 'quantity', 'warranty', 'weight', 'delivery_text', 'manufacturer', 'image', 'product_with_gift', 'barcode_format');

   $fs = fopen('csv.csv', 'w');
   fputcsv($fs, $columns);      
   fclose($fs);

   // Iterate through each <product> node
   $node = $xml->xpath('//product');

   foreach ($node as $n) {               
       // Iterate through each child of <item> node
       foreach ($columns as $col) {         
           if (count($xml->xpath('//product['.$i.']/'.$col)) > 0) {
              $values[] = trim($xml->xpath('//product['.$i.']/'.$col)[0]);
           } else {
              $values[] = '';
           }    
       }    
       // Write to CSV files (appending to column headers)
       $fs = fopen('csv.csv', 'a');
       fputcsv($fs, $values);      
       fclose($fs);  

       $values = [];    // Clean out array for next <item> (i.e., row)
       $i++;            // Move to next <item> (i.e., node position)
   }
}
?>

mid、premium xml、php的任何解决方案?

标签: phpxmlcsv

解决方案


问题是您试图仅使用images标记作为起点来获取节点列表,因为子节点有自己的内容,它们不会出现在更高级别的节点文本中。

我对代码进行了一些更改,但我现在也使用该<image>元素来获取数据。此代码不假定每个项目只有一个节点,因此当它使用 XPath 时,它总是循环遍历所有项目并将它们构建成单个字符串,然后再将它们添加到 CSV。

$filexml = 'imp2.xml';

if (file_exists($filexml))  {
    // Only open file once you know it exists
    $xml = simplexml_load_file($filexml);
    $i = 1;           // Position counter
    $values = [];     // PHP array

    // Writing column headers
    $columns = array('id', 'barcode', 'title', 'description', 'price', 'sec_costs', 'quantity', 'warranty', 'weight', 'delivery_text', 'manufacturer', 'image', 'product_with_gift', 'barcode_format');

    // Open output file at start
    $fs = fopen('csv.csv', 'w');
    fputcsv($fs, $columns);

    // Iterate through each <product> node
    $node = $xml->xpath('//product');

    foreach ($node as $n) {
        // Iterate through each child of <item> node
        foreach ($columns as $col) {
            // Use //'.$col so node doesn't have to be directly under product
            $dataMatch = $xml->xpath('//product['.$i.']//'.$col);
            if (count($dataMatch) > 0) {
                // Build list of all matches
                $newData = '';
                foreach ( $dataMatch as $data)  {
                    $newData .= trim((string)$data).",";
                }
                // Remove last comma before adding it in
                $values[] = rtrim($newData, ",");
            } else {
                $values[] = '';
            }
        }
        fputcsv($fs, $values);

        $values = [];    // Clean out array for next <item> (i.e., row)
        $i++;            // Move to next <item> (i.e., node position)
    }
    // Close file only at end
    fclose($fs);
}

推荐阅读