您好我正在进行操作,我需要将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
我需要所有的价值观。
请帮助我做错了。
答案 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提供的此特定字符串。
<?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
)
)