我有一个自动转换类的这一部分,它自动遍历XML文件:
$xpath = new DOMXPath($doc);
$entries = $xpath->evaluate($this->item,$doc);
$csv = array();
$i = 1;
foreach($entries as $el) {
foreach($el->childNodes as $node) {
if(!empty($map)) {
// not a real node OR not in the mapped array, and only mapped fields should be output
if($node->nodeType==3 or (!in_array($node->nodeName,$map) and $this->selectedFields)) continue;
if(!in_array($node->nodeName,$map)) {
$csv[0][$node->nodeName]=$node->nodeName;
$csv[1][$node->nodeName]=$node->nodeName;
$csv[$i][$node->nodeName] = $node->textContent;
} else {
$csv[0][$node->nodeName]=$remap[$node->nodeName];
$csv[$i][$remap[$node->nodeName]] = $node->textContent;
}
} else {
if($node->nodeType==3) continue;
$csv[0][$node->nodeName]=$node->nodeName;
$csv[1][$node->nodeName]=$node->nodeName;
$csv[$i][$node->nodeName] = $node->textContent;
}
}
$i++;
}
XML树的一个项目如下所示:
<cac:Item>
<cbc:Description>BREMSBELAG GALFER ORGAN. FD171-G1054 (KBA)</cbc:Description>
<cac:SellersItemIdentification>
<cac:ID>04303400</cac:ID>
</cac:SellersItemIdentification>
<cac:StandardItemIdentification>
<cac:ID identificationSchemeID="EAN/UCC-13">8400160001718</cac:ID>
</cac:StandardItemIdentification>
<cac:ManufacturersItemIdentification>
<cac:ID>FD171-G1054</cac:ID>
<cac:IssuerParty>
<cac:PartyName>
<cbc:Name>Galfer</cbc:Name>
</cac:PartyName>
</cac:IssuerParty>
</cac:ManufacturersItemIdentification>
<cac:BasePrice>
<cbc:PriceAmount amountCurrencyID="EUR">5.95</cbc:PriceAmount>
<cbc:BaseQuantity quantityUnitCode="EA">1</cbc:BaseQuantity>
</cac:BasePrice>
<cac:RecommendedRetailPrice>
<cbc:PriceAmount amountCurrencyID="EUR">10.9</cbc:PriceAmount>
<cbc:BaseQuantity quantityUnitCode="EA">1</cbc:BaseQuantity>
</cac:RecommendedRetailPrice>
</cac:Item>
输出几乎是完美的:
Beschreibung,Hartje-ID,EAN,“Hersteller ID”,Einkaufspreis,Verkaufspreis,Packemenge,Artikelinformation“BREMSBELAG GALFER ORGAN.FD171-G1054(KBA)”,“04303400”,“8400160001718”,“FD171-G1054 Galfer” ,“5.95 1”,“10.9 1”
但你可以看到,RecommandedRetailPrice(Verkaufspreis)是从它的子节点混合而来的,但是我需要它们与它们自己的标题分开。
希望你有个主意。谢谢。
答案 0 :(得分:1)
自动转换是一个非常糟糕的主意,你将丢失DOM(和命名空间)的结构信息,你将失去使用Xpath的可能性。 XML示例也被破坏了。缺少名称空间定义(xmlns:cac =“”和xmlns:cbc =“”)。
DOM是一个数据源,您可以使用表达式(想想sql语句)来定义所需的数据源部分。明确:
$dom = new DOMDocument();
$dom->load($xmlFile);
$xpath = new DOMXpath($dom);
// register namespaces - check the source document for the correct namespace strings
$xpath->registerNamespace('cac', 'urn:cac');
$xpath->registerNamespace('cbc', 'urn:cbc');
// define xpath expressions for the columns
$columns = [
'Beschreibung' => 'string(cbc:Description)',
'Hartje-ID' => 'string(cac:SellersItemIdentification/cac:ID)',
'EAN' => 'string(cac:StandardItemIdentification/cac:ID)',
'Hersteller ID' => 'string(cac:ManufacturersItemIdentification/cac:ID)',
'Einkaufspreis' => 'number(cac:BasePrice/cbc:PriceAmount)',
'Verkaufspreis' => 'number(cac:RecommendedRetailPrice/cbc:PriceAmount)',
'Packemenge' => 'number(cac:BasePrice/cbc:BaseQuantity)'
];
// open a file stream for the standard output
$csvStream = fopen('php://stdout', 'w');
// write the columns names
fputcsv($csvStream , array_keys($columns));
//iterate all items
foreach ($xpath->evaluate('//cac:Item') as $item) {
// a row for an item
$row = [];
foreach ($columns as $expression) {
// use the expression to fetch data for the columns and add it
$row[] = $xpath->evaluate($expression, $item);
}
// write to the output stream
fputcsv($csvStream, $row);
}
输出:
Beschreibung,Hartje-ID,EAN,"Hersteller ID",Einkaufspreis,Verkaufspreis,Packemenge
"BREMSBELAG GALFER ORGAN. FD171-G1054 (KBA)",04303400,8400160001718,FD171-G1054,5.95,10.9,1