php - 使用 simplexml 将 XML 导入 MySQL

标签 php mysql xml foreach

我尝试使用此页面中的一些脚本来用于我的网上商店。我想将 XML 文件导入到我的 MySQL 数据库中。我让脚本正常工作,但只导入了第一个订单行,而不是第二个。

这是我的 XML 代码的示例:

<?xml version="1.0" encoding="UTF-8"?>
<eWebBooking>
   <OrderHead>
      <Action>SendFromWarehouse</Action>
      <OrderReference>5986-20193315</OrderReference>
      <EarliestOrderDate/>
      <OrderNumber>20193315</OrderNumber>
      <SalesOrg>Web</SalesOrg>
      <DistChannel>Parcel</DistChannel>
      <InvoiceReference>Reknes</InvoiceReference>
      <Orderer>
         <Name>Ola Nordamann</Name>
         <Telephone>22225555</Telephone>
         <Email/>
         <StreetName>Hackerstreet 46</StreetName>
         <PostalCode>5986</PostalCode>
         <Region>LEGOLAND</Region>
      </Orderer>
   </OrderHead>


   <OrderLines>
      <OrderLine>1</OrderLine>
      <ArticleNo>10501</ArticleNo>
      <ArticleDescription>MPOW Dunmer Earphone Blueth</ArticleDescription>
      <ArticleBrand>MPOW</ArticleBrand>
      <DlvDate>2016-09-09</DlvDate>
      <NoOfPieces>1</NoOfPieces>
      <DeliveryStore>eWeb</DeliveryStore>
      <DeliveryCode>DELIVERY</DeliveryCode>
      <Weight>0,2</Weight>
      <Volume>70</Volume>
      <ShipmentNo>73600698093661246</ShipmentNo>
      <ParcelNo>373600596034663364</ParcelNo>
   </OrderLines>
   <OrderLines>
      <OrderLine>2</OrderLine>
      <ArticleNo>10528</ArticleNo>
      <ArticleDescription>Mpow MBS5 Armor Bluetooth</ArticleDescription>
      <ArticleBrand>MPOW</ArticleBrand>
      <DlvDate>2016-09-07</DlvDate>
      <NoOfPieces>1</NoOfPieces>
      <DeliveryStore>eWeb</DeliveryStore>
      <DeliveryCode>PICKUP</DeliveryCode>
      <Weight>4</Weight>
      <Volume>50</Volume>
      <ShipmentNo>73600698093661246</ShipmentNo>
      <ParcelNo>00373600698636066394</ParcelNo>
    </OrderLines>
</eWebBooking>


我想我必须更改一些 foreach 代码?
这是我的 PHP 文件/代码的副本:

<?php

ini_set('display_errors','On');

$con2 = mysql_connect("databasehost","databaseuser","databasepass");
if (!$con2)  {  
    die('Could not connect: ' . mysql_error());  
}

$selectdb = mysql_select_db("databasename", $con2);
if (!$selectdb)  { 
    die('Database not used: ; ' . mysql_error());  
}

$file_arr = array();

if ($handle = opendir('.')) {
    while (false !== ($file = readdir($handle))) {
        if (($file != ".") && ($file != "..")) {
            if(substr($file, -4) == ".xml")
            {
                array_push($file_arr, $file);
            }
        }
    }
    closedir($handle);
}

    foreach($file_arr as $filename)

{
     $xml = simplexml_load_file($filename);

    $Action = mysql_real_escape_string($xml->OrderHead->Action);
    $OrderReference = mysql_real_escape_string($xml->OrderHead->OrderReference);    
    $EarliestOrderDate = mysql_real_escape_string($xml->OrderHead->EarliestOrderDate);
    $OrderNumber = mysql_real_escape_string($xml->OrderHead->OrderNumber);
    $SalesOrg = mysql_real_escape_string($xml->OrderHead->SalesOrg);
    $DistChannel = mysql_real_escape_string($xml->OrderHead->DistChannel);
    $InvoiceReference = mysql_real_escape_string($xml->OrderHead->InvoiceRefernce);
    $Name = mysql_real_escape_string($xml->OrderHead->Orderer->Name);
    $Telephone = mysql_real_escape_string($xml->OrderHead->Orderer->Telephone);
    $Email = mysql_real_escape_string($xml->OrderHead->Orderer->Email);
    $StreetName = mysql_real_escape_string($xml->OrderHead->Orderer->StreetName);
    $PostalCode = mysql_real_escape_string($xml->OrderHead->Orderer->PostalCode);
    $Region = mysql_real_escape_string($xml->OrderHead->Orderer->Region);


    $OrderLine = mysql_real_escape_string($xml->OrderLines->OrderLine);
    $ArticleNo = mysql_real_escape_string($xml->OrderLines->ArticleNo);
    $ArticleDescription = mysql_real_escape_string($xml->OrderLines->ArticleDescription);
    $ArticleBrand = mysql_real_escape_string($xml->OrderLines->ArticleBrand);
    $DlvDate = mysql_real_escape_string($xml->OrderLines->DlvDate);
    $NoOfPieces = mysql_real_escape_string($xml->OrderLines->NoOfPieces);
    $DeliveryStore = mysql_real_escape_string($xml->OrderLines->DeliveryStore);
    $DeliveryCode = mysql_real_escape_string($xml->OrderLines->DeliveryCode);
    $Weight = mysql_real_escape_string($xml->OrderLines->Weight);
    $Volume = mysql_real_escape_string($xml->OrderLines->Volume);
    $ShipmentNo = mysql_real_escape_string($xml->OrderLines->ShipmentNo);
    $ParcelNo = mysql_real_escape_string($xml->OrderLines->ParcelNo);
    $TimeWindowStart = mysql_real_escape_string($xml->OrderLines->TimeWindowStart);
    $TimeWindowEnd = mysql_real_escape_string($xml->OrderLines->TimeWindowEnd);


    mysql_query("INSERT INTO xml (Action, OrderReference, EarliestOrderDate, OrderNumber, SalesOrg, DistChannel, InvoiceReference, Name, Telephone, Email, StreetName, PostalCode, Region, OrderLine, ArticleNo, ArticleDescription, ArticleBrand, DlvDate, NoOfPieces, DeliveryStore, DeliveryCode, Weight, Volume, ShipmentNo, ParcelNo, TimeWindowStart, TimeWindowEnd)
    VALUES ('$Action', '$OrderReference', '$EarliestOrderDate', '$OrderNumber', '$SalesOrg', '$DistChannel', '$InvoiceReference', '$Name', '$Telephone', '$Email', '$StreetName', '$PostalCode', '$Region', '$OrderLine', '$ArticleNo', '$ArticleDescription', '$ArticleBrand', '$DlvDate', '$NoOfPieces', '$DeliveryStore', '$DeliveryCode', '$Weight', '$Volume', '$ShipmentNo', '$ParcelNo', '$TimeWindowStart', '$TimeWindowEnd')")
    or die(mysql_error());


    printf ("Records inserted: %d\n", mysql_affected_rows());  
    echo " <p />--- --- --- --- --- --- --- --- ---<p />";
}

mysql_close($con2);

?>

最佳答案

考虑 MySQL 的 LOAD XML LOCAL INFILE用于批量导入 XML 文档。但是,要使用此命令,必须简化 XML 以与数据库字段和值保持一致。要重组原始文档以进行此类导入,请考虑 XSLT (用于操作源文档的 XML 转换语言)。 XSLT 可以将原始 XML 转换为更简单、更扁平的结构以供数据库上传。 PHP 使用libxslt 维护XSLT 1.0 处理器。引擎。

XSLT 脚本(另存为 .xsl 文件以便在下面的 PHP 中读取)

<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output version="1.0" encoding="UTF-8" indent="yes" />
<xsl:strip-space elements="*"/>

  <xsl:template match="/eWebBooking">
     <xsl:copy>
        <xsl:apply-templates select="OrderLines"/>
     </xsl:copy>
  </xsl:template>

  <xsl:template match="OrderLines"> 
   <xsl:copy>          
       <xsl:copy-of select="ancestor::eWebBooking/OrderHead/*[not(local-name()='Orderer')]"/>
       <xsl:copy-of select="ancestor::eWebBooking/OrderHead/Orderer/*"/>
       <xsl:copy-of select="*"/>
   </xsl:copy>
  </xsl:template>    
</xsl:transform>

PHP脚本(下面使用PDO连接MySQL;您可能需要启用php_xsl扩展并在MYSQL中设置-local-infile)

$file_arr = array();

if ($handle = opendir('.')) {
    while (false !== ($file = readdir($handle))) {
        if (($file != ".") && ($file != "..")) {
            if(substr($file, -4) == ".xml")
            {
                array_push($file_arr, $file);
            }
        }
    }
    closedir($handle);
}

foreach($file_arr as $filename) {

     // LOAD XML AND XSL SOURCES
     $doc = simplexml_load_file($filename);
     $xsl = simplexml_load_file('XSLTScript.xsl');

     // TRANSFORM SOURC
     $proc = new XSLTProcessor;
     $proc->importStyleSheet($xsl); 
     $newDoc = $proc->transformToXML($doc);

     // SAVE OUTPUT TO FILE         
     $xmlfile = 'temp.xml';
     file_put_contents($xmlfile, $newDoc);

     // RUN MYSQL COMMAND 
     try {
        $db = new PDO('mysql:host=databasehost;dbname=databasename', 
                      $databaseuser, $databasepwd); 
        $db->query("LOAD XML DATA INFILE 'path/to/temp.xml'
                    INTO TABLE xml
                    ROWS IDENTIFIED BY '<OrderLines>';");
     } catch(PDOException $e) {  
            echo $e->getMessage(); 
     } 
}

转换后的 XML (要导入到数据库中,所有元素名称必须与数据库名称匹配)

<?xml version="1.0" encoding="UTF-8"?>
<eWebBooking>
  <OrderLines>
    <Action>SendFromWarehouse</Action>
    <OrderReference>5986-20193315</OrderReference>
    <EarliestOrderDate/>
    <OrderNumber>20193315</OrderNumber>
    <SalesOrg>Web</SalesOrg>
    <DistChannel>Parcel</DistChannel>
    <InvoiceReference>Reknes</InvoiceReference>
    <Name>Ola Nordamann</Name>
    <Telephone>22225555</Telephone>
    <Email/>
    <StreetName>Hackerstreet 46</StreetName>
    <PostalCode>5986</PostalCode>
    <Region>LEGOLAND</Region>
    <OrderLine>1</OrderLine>
    <ArticleNo>10501</ArticleNo>
    <ArticleDescription>MPOW Dunmer Earphone Blueth</ArticleDescription>
    <ArticleBrand>MPOW</ArticleBrand>
    <DlvDate>2016-09-09</DlvDate>
    <NoOfPieces>1</NoOfPieces>
    <DeliveryStore>eWeb</DeliveryStore>
    <DeliveryCode>DELIVERY</DeliveryCode>
    <Weight>0,2</Weight>
    <Volume>70</Volume>
    <ShipmentNo>73600698093661246</ShipmentNo>
    <ParcelNo>373600596034663364</ParcelNo>
  </OrderLines>
  <OrderLines>
    <Action>SendFromWarehouse</Action>
    <OrderReference>5986-20193315</OrderReference>
    <EarliestOrderDate/>
    <OrderNumber>20193315</OrderNumber>
    <SalesOrg>Web</SalesOrg>
    <DistChannel>Parcel</DistChannel>
    <InvoiceReference>Reknes</InvoiceReference>
    <Name>Ola Nordamann</Name>
    <Telephone>22225555</Telephone>
    <Email/>
    <StreetName>Hackerstreet 46</StreetName>
    <PostalCode>5986</PostalCode>
    <Region>LEGOLAND</Region>
    <OrderLine>2</OrderLine>
    <ArticleNo>10528</ArticleNo>
    <ArticleDescription>Mpow MBS5 Armor Bluetooth</ArticleDescription>
    <ArticleBrand>MPOW</ArticleBrand>
    <DlvDate>2016-09-07</DlvDate>
    <NoOfPieces>1</NoOfPieces>
    <DeliveryStore>eWeb</DeliveryStore>
    <DeliveryCode>PICKUP</DeliveryCode>
    <Weight>4</Weight>
    <Volume>50</Volume>
    <ShipmentNo>73600698093661246</ShipmentNo>
    <ParcelNo>00373600698636066394</ParcelNo>
  </OrderLines>
</eWebBooking>

关于php - 使用 simplexml 将 XML 导入 MySQL,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39310051/

相关文章:

mysql - Joomla 2.5 连接 3 个表

xml - 解码 XML 注释

php - 使用 file_get_contents() 加载远程 xml 页面

javascript - 使用AJAX : Send variables to a PHP file which generate XML from a Database

php - 从 oscommerce 中删除不活跃的产品

MySql 简单案例表达式不返回正确的数据

php - 一键插入数据库并为该数据调用 AJAX

Java - 将 Web 服务响应 (StreamResult) 转换为 XML 以检索子值

javascript - 将变量从 JS 发布到 PHP 时遇到问题

PHP:将动态数量的值添加到 MySQL 数据库中