使用php将xml转换为Nth级别的csv

时间:2017-05-10 06:54:17

标签: php xml csv

您好我正在进行操作,我需要将xml转换为csv文件

以下是我的xml文件格式。

<CatalogLine>
            <Item>
               <ItemID agencyRole="MasterProductNumber">
                  <ID>11802</ID>
               </ItemID>
               <ItemID agencyRole="Prefix_Number">
                  <ID>FOL</ID>
               </ItemID>
               <ItemID agencyRole="Stock_Number">
                  <ID>00374EA</ID>
               </ItemID>
            </Item>
            <UOMCode>EA</UOMCode>
            <ItemPrice>
               <UnitPrice>
                  <Amount currencyID="USD">0</Amount>
                  <PerQuantity unitCode="EA">1</PerQuantity>
                  <Code>Catalog_List_Amount</Code>
               </UnitPrice>
            </ItemPrice>
            <Note type="Page_Number">5</Note>
</CatalogLine>

同样超过500次。

所以我需要csv中的所有数据,如

MasterProductNumber Prefix_Number   Stock_Number    UOMCode Amount  PerQuantity Code                    Page_Number 
11802               FOL             00374EA         EA      0       1           Catalog_List_Amount     5

以下代码我尝试过:

<?php

$filexml='ddsource.xml';
if (file_exists($filexml))  {

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

   // Writing column headers
   $columns = array('MasterProductNumber','Prefix_Number','Stock_Number','UOMCode','Amount','PerQuantity','Code','Page_Number');

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

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

   foreach ($node as $n) {           

       // Iterate through each child of <item> node
       $child = $xml->xpath('//CatalogLine['.$i.']/*');      

       foreach ($child as $value) {
          $values[] = $value;         
       }

       // Write to CSV files (appending to column headers)
       $fs = fopen('ddsource1.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)
   }
}
?>

但它只提供主节点值: UOMCode - EA 注 - 5

我需要所有的价值观。

请帮助我做错了。

3 个答案:

答案 0 :(得分:1)

我没有测试它,因为我写得很快。看看这个例子,它可能很有用。

$xml_content_payload = '
    <CatalogLine>
        <Item>
            <ItemID agencyRole="MasterProductNumber">
                <ID>11802</ID>
            </ItemID>
            <ItemID agencyRole="Prefix_Number">
                <ID>FOL</ID>
            </ItemID>
            <ItemID agencyRole="Stock_Number">
                <ID>00374EA</ID>
            </ItemID>
        </Item>
        <UOMCode>EA</UOMCode>
        <ItemPrice>
            <UnitPrice>
                <Amount currencyID="USD">0</Amount>
                <PerQuantity unitCode="EA">1</PerQuantity>
                <Code>Catalog_List_Amount</Code>
            </UnitPrice>
        </ItemPrice>
        <Note type="Page_Number">5</Note>
    </CatalogLine>';

$xml_reader = new \XMLReader();
$xml_reader->xml($xml_content_payload); // use the $xml_reader->open('file.xml'); to open a file

//this loop reads node by node from xml file/payload
while ($xml_reader->read()) {
    if ($xml_reader->nodeType === \XMLReader::ELEMENT && $xml_reader->name === 'CatalogLine') { //put your name of node what you want to catch
        $element = simplexml_load_string($xml_reader->readOuterXml());
        // ..process your element
        // as $element you have \SimpleXMLElement::class object with all CatalogLine's childrens
        $xml_reader->next();
    }
}

这是清除读取非常大的xml文件并逐节点处理它们的最佳方法

我希望我帮助过。祝你好运!

答案 1 :(得分:1)

$xml='<?xml version="1.0" encoding="UTF-8"?>
        <root>
            <CatalogLine>
                <Item>
                   <ItemID agencyRole="MasterProductNumber">
                      <ID>11802</ID>
                   </ItemID>
                   <ItemID agencyRole="Prefix_Number">
                      <ID>FOL</ID>
                   </ItemID>
                   <ItemID agencyRole="Stock_Number">
                      <ID>00374EA</ID>
                   </ItemID>
                </Item>
                <UOMCode>EA</UOMCode>
                <ItemPrice>
                   <UnitPrice>
                      <Amount currencyID="USD">0</Amount>
                      <PerQuantity unitCode="EA">1</PerQuantity>
                      <Code>Catalog_List_Amount</Code>
                   </UnitPrice>
                </ItemPrice>
                <Note type="Page_Number">5</Note>
            </CatalogLine>
            <CatalogLine>
                <Item>
                   <ItemID agencyRole="MasterProductNumber">
                      <ID>12803</ID>
                   </ItemID>
                   <ItemID agencyRole="Prefix_Number">
                      <ID>FOL</ID>
                   </ItemID>
                   <ItemID agencyRole="Stock_Number">
                      <ID>00374FA</ID>
                   </ItemID>
                </Item>
                <UOMCode>EP</UOMCode>
                <ItemPrice>
                   <UnitPrice>
                      <Amount currencyID="USD">34</Amount>
                      <PerQuantity unitCode="EA">1</PerQuantity>
                      <Code>Catalog_List_Amount</Code>
                   </UnitPrice>
                </ItemPrice>
                <Note type="Page_Number">5</Note>
            </CatalogLine>
            <CatalogLine>
                <Item>
                   <ItemID agencyRole="MasterProductNumber">
                      <ID>15603</ID>
                   </ItemID>
                   <ItemID agencyRole="Prefix_Number">
                      <ID>WKI</ID>
                   </ItemID>
                   <ItemID agencyRole="Stock_Number">
                      <ID>45374FA</ID>
                   </ItemID>
                </Item>
                <UOMCode>XY</UOMCode>
                <ItemPrice>
                   <UnitPrice>
                      <Amount currencyID="UKP">69</Amount>
                      <PerQuantity unitCode="EA">36</PerQuantity>
                      <Code>Catalog_List_Amount</Code>
                   </UnitPrice>
                </ItemPrice>
                <Note type="Page_Number">42</Note>
            </CatalogLine>
        </root>';


    libxml_use_internal_errors( true );
    $dom=new DOMDocument;
    $dom->validateOnParse=false;
    $dom->standalone=true;
    $dom->strictErrorChecking=false;
    $dom->recover=true;
    $dom->formatOutput=false;

    $dom->loadXML( $xml );
    $errors=serialize( libxml_get_last_error() );
    libxml_clear_errors();

    $cats=$dom->getElementsByTagName('CatalogLine');




    if( !empty( $cats ) && $cats->length > 0 ){
        /* column headers for use in csv */
        $columns = array(
            'MasterProductNumber',
            'Prefix_Number',
            'Stock_Number',
            'UOMCode',
            'Amount',
            'PerQuantity',
            'Code',
            'Page_Number'
        );
        /* output file location */
        $file=__DIR__ . '/so_csv.csv';

        /* placeholder array to store results for later writing to csv */
        $data=array();

        foreach( $cats as $cat ){

            $item=$cat->childNodes->item(1);
            $ip=$cat->childNodes->item(5);
            $note=trim( $cat->childNodes->item(7)->nodeValue );
            $up=$ip->childNodes->item(1);

            $uom=trim( $cat->childNodes->item(3)->nodeValue );
            $amount=trim( $up->childNodes->item(1)->nodeValue );
            $qty=trim( $up->childNodes->item(3)->nodeValue );
            $code=trim( $up->childNodes->item(5)->nodeValue );

            /* get a list of ItemIDs*/
            $colitems=$item->getElementsByTagName('ItemID');
            foreach( $colitems as $itemid ){
                if( $itemid->hasAttribute( 'agencyRole' ) ){
                    /*
                        Assign each as a variable variable - these then match
                        the column values [0-2]
                    */
                    ${$itemid->getAttribute( 'agencyRole' )}=trim( $itemid->nodeValue );
                }
            }

            /*
                Generate an array with the values found from querying the XML
            */
            $data[]=array(
                $columns[0] =>  ${$columns[0]},
                $columns[1] =>  ${$columns[1]},
                $columns[2] =>  ${$columns[2]},
                $columns[3] =>  $uom,
                $columns[4] =>  $amount,
                $columns[5] =>  $qty,
                $columns[6] =>  $code,
                $columns[7] =>  $note
            );
        }
        /*
            Write the headers and csv data to file
        */
        if( !empty( $data ) ){
            $f = fopen( $file, 'w' );
            fputcsv( $f, $columns );
            foreach($data as $arr)fputcsv($f,$arr);
            fclose($f);

            echo count( $data ) . ' lines added to ' . $file;
        }
    }
    $dom=null;

答案 2 :(得分:1)

此解决方案适用于OP提供的此特定字符串。

Try this code snippet here

<?php

ini_set('display_errors', 1);
$string='<CatalogLine>
            <Item>
               <ItemID agencyRole="MasterProductNumber">
                  <ID>11802</ID>
               </ItemID>
               <ItemID agencyRole="Prefix_Number">
                  <ID>FOL</ID>
               </ItemID>
               <ItemID agencyRole="Stock_Number">
                  <ID>00374EA</ID>
               </ItemID>
            </Item>
            <UOMCode>EA</UOMCode>
            <ItemPrice>
               <UnitPrice>
                  <Amount currencyID="USD">0</Amount>
                  <PerQuantity unitCode="EA">1</PerQuantity>
                  <Code>Catalog_List_Amount</Code>
               </UnitPrice>
            </ItemPrice>
            <Note type="Page_Number">5</Note>
</CatalogLine>';
//optionally you can load string like this
//$string=  file_get_contents("/path/to/file.txt");
$object= simplexml_load_string($string);
$headers=array();
$values=array();
foreach($object->Item->ItemID as $key => $items)
{
    $headers[]=(string)$items["agencyRole"];
}
foreach($object->Item->ItemID as $key => $items)
{
    $values[]=(string)$items->ID;
}
foreach((array)$object->ItemPrice->UnitPrice as $key => $value)
{
    $headers[]=$key;
    $values[]=$value;
}

$headers[]=(string)$object->Note["type"];
$values[]=(string)$object->Note;

print_r(array($headers,$values));

<强>输出:

Array
(
    [0] => Array
        (
            [0] => MasterProductNumber
            [1] => Prefix_Number
            [2] => Stock_Number
            [3] => Amount
            [4] => PerQuantity
            [5] => Code
            [6] => Page_Number
        )

    [1] => Array
        (
            [0] => 11802
            [1] => FOL
            [2] => 00374EA
            [3] => 0
            [4] => 1
            [5] => Catalog_List_Amount
            [6] => 5
        )

)
相关问题