Php 使用显示所有子元素的DOMXpath进行XML解析

Php 使用显示所有子元素的DOMXpath进行XML解析,php,xml,parsing,dom,xpath,Php,Xml,Parsing,Dom,Xpath,我有一个自动转换类的这一部分,它自动遍历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($ma

我有一个自动转换类的这一部分,它自动遍历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>

布雷姆贝拉格·高尔弗风琴。FD171-G1054(KBA)
04303400
8400160001718
FD171-G1054
高尔弗
5.95
1.
10.9
1.
输出几乎完美:

Beschreibung,Hartje ID,EAN,“Hersteller ID”,Einkaufspreis,Verkaufspreis,Packemenge,Artikelinformation“BREMSBELAG GALFER器官。FD171-G1054(KBA)”,“04303400”,“8400160001718”,“FD171-G1054 GALFER”,“5.95 1”,“10.9 1”

但是您可以看到RecommandeRetailPrice(Verkaufspreis)是从它的子节点混合而来的,但是我需要它们与它们自己的头分开


希望你有个主意。谢谢。

自动转换是一个非常糟糕的主意,它会丢失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