【问题标题】:XML to CSV in PHPPHP 中的 XML 到 CSV
【发布时间】:2019-08-29 02:42:56
【问题描述】:

我正在尝试使用下面的代码将 XML 转换为 CSV,但它仅在只有一行时才有效。多个条目将仅显示标题/列名。

这就是我的 XML 的样子:

<Cars>
  <Type>B</Type>
  <Car>
    <Brand>Car1</Brand>
    <Model>M1</Model>
    <Year>2010</Year>
    <Age>9</Age>
    <Desciption>test</Desciption>
  </Car>
</Cars>


<Cars>
  <Type>B</Type>
  <Car>
    <Brand>Car2</Brand>
    <Model>M2</Model>
    <Year>2015</Year>
    <Age>4</Age>
    <Desciption>test</Desciption>
  </Car>
</Cars>

我的代码:

 $filexml='cars.xml';

  $cname=array();

  $cname[] = 'Brand';
  $cname[] = 'Model';
  $cname[] = 'Year';
  $cname[] = 'Age';
  $cname[] = 'Desciption';


  if (file_exists($filexml)) {
      $xml = simplexml_load_file($filexml); 
      $f = fopen('cars.csv', 'w') or die('Can\'t create .csv file, try again later.');
      fputcsv($f, $cname);

      foreach ($xml->Car as $Car) {
        fputcsv($f, get_object_vars($Car),',','"');
      } 

      fclose($f);

  }

【问题讨论】:

    标签: php xml csv fputcsv


    【解决方案1】:

    对于每个子节点/标签,您必须使用__toString() 方法。

    像这样:

    foreach ($xml->Car as $Car) {
        $row = [];
        foreach ($cname as $node) {
            // Here we address to the Car's child node with name from your array above
            $row[$node] = $Car->{$node}->__toString();
        }
    
        fputcsv($f, $row, ',' ,'"');
    } 
    
    fclose($f);
    

    【讨论】:

    • 哦,我明白了。为什么在您的 XML 代码中有 2 个 &lt;Cars&gt; 块,每个块中有一个子块?
    • 这就是它的结构,因为它是来自某个页面的响应形式。
    • 但这不正确 - 在 XML 中必须只有一个根节点。或者我不明白你:) 也许这有帮助:你不仅必须在一个循环中加载-&gt;Car,而且还必须加载-&gt;Cars-&gt;Car,因为你必须加载Cars 个节点。
    • 已经试过了,还是不行。是否可以在转换之前清理 XML 格式?
    • 我认为你可以只用一个根节点(如&lt;root&gt;&lt;/root&gt;)包装你的xml字符串。然后,您可以像我上面写的那样去每个root-&gt;Cars-&gt;Car。但首先,当然,您必须从文件中获取 xml-string(用于包装)并使用 simplexml_load_string 而不是 simplexml_load_file
    【解决方案2】:

    假设您的 XML 实际上是有效的(只有一个根元素),那么结构的简化视图是这样的:

    <document>
        <Cars>
           <Car>
              <Brand>Car1</Brand>
           </Car>
        </Cars>
        <Cars>
           <Car>
              <Brand>Car2</Brand>
           </Car>
        </Cars>
    </document>
    

    注意,同一级别有多个Cars节点,但每个节点中只有一个Car

    当您加载 XML 时,您的初始 PHP 变量将代表 &lt;document&gt; 元素。

    因此您可以像这样手动访问前两个品牌((string) 从 XML 元素中获取文本内容):

    • (string)$xml-&gt;Cars[0]-&gt;Car-&gt;Brand
    • (string)$xml-&gt;Cars[1]-&gt;Car-&gt;Brand

    要获取所有品牌,需要循环$xml-&gt;Cars

    foreach ( $xml->Cars as $CarsNode ) {
       $CarNode = $CarsNode->Car;
       $brand = (string)$CarNode->Brand;
    }
    

    从那里,您可以使用现有代码将一行写入 CSV 文件。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-01-09
      • 1970-01-01
      • 2013-09-10
      • 2015-08-22
      • 2019-03-28
      相关资源
      最近更新 更多