【问题标题】:XMLReader php xml insert to mysql duplicatesXMLReader php xml 插入到 mysql 重复项
【发布时间】:2022-10-05 19:18:43
【问题描述】:

我有一个 XML:

<?xml version=\"1.0\" encoding=\"UTF-8\"?>
<products currency=\"EUR\">
<product id=\"457654754\" vat=\"13.0\">
    <price gross=\"0.09\" net=\"0.07\"/>
    <sizes>
        <size id=\"0\"  name=\"gfdgfdgfdg\" panel_name=\"dfgfdgfdgfd\" code_producer=\"fgdfgfdg\"  
         iaiext:code_external=\"457547547547\"  code=\"354643643643\"  weight=\"4\"  iaiext:weight_net=\"10\" >
        <stock id=\"1\" quantity=\"333\"/>
        </size>
    </sizes>
</product>
</products>

当我将其解析为:

<?php
$xml = new XMLReader;
$xml->open(\'XML_URL\');
while ($xml->read()) {
if ($xml->nodeType === XMLReader::ELEMENT && $xml->name == \'product\')
    echo $xml->getAttribute(\'id\').\'<br />\';
if ($xml->nodeType === XMLReader::ELEMENT && $xml->name == \'price\')
    echo $xml->getAttribute(\'net\').\'<br />\';
if ($xml->nodeType === XMLReader::ELEMENT && $xml->name == \'size\')
    echo $xml->getAttribute(\'iaiext:code_external\').\'<br />\';
    if ($xml->nodeType === XMLReader::ELEMENT && $xml->name == \'stock\')
    echo $xml->getAttribute(\'quantity\').\'<br />\';
 }

 ?>

我得到正确显示的值。 但是如何将它们插入到 mysql 表中? 我在同一个while循环中尝试了它,而不是例如2500行超过48000行作为重复项。 我怎样才能实现它?

数据库

CREATE TABLE `table` (
`auto_increm` int(11) NOT NULL,
`un_id` int(11) NOT NULL,
`price` decimal(15,2) NOT NULL,
`quantity` int(11) NOT NULL,
`ean` varchar(255) NOT NULL
 ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3;

 ALTER TABLE `table`
 ADD PRIMARY KEY (`auto_increm`);

 ALTER TABLE `table`
 MODIFY `auto_increm` int(11) NOT NULL AUTO_INCREMENT;
 COMMIT;

php 中的 id 属性 = mysql 表中的 un_id

php 中的 net 属性 = mysql 表中的价格

iaiext:php 中的code_external 属性 = mysql 表中的 ean

php 中的数量属性 = mysql 表中的数量。


在平面 XML 中,我总是能够执行插入操作,例如:

<?php    
$doc = new DOMDocument();
$doc->load(\'feed.xml\');
$arrFeeds = array();
foreach ($doc->getElementsByTagName(\'item\') as $node) {
$itemRSS = array ( 
 \'sku\' => $node->getElementsByTagName(\'itemcode\')->item(0)->nodeValue,
  \'stock\' => $node->getElementsByTagName(\'stock\')->item(0)->nodeValue,
     \'price\' => $node->getElementsByTagName(\'price_eur\')->item(0)->nodeValue
   );
   array_push($arrFeeds, $itemRSS);

  }


  $counter = 0;
  foreach( $arrFeeds as $RssItem){
  $sku = $RssItem[\"sku\"];
  $stock = $RssItem[\"stock\"];
  $price = $RssItem[\"price\"];
  $sql = \"INSERT INTO table(sku,stock,price) VALUES (\" . $sku . \"\',\" . 
  $stock . \"\',\" . $price . \"\')\";
  $counter++;
  $result = mysqli_query($conn, $sql);

  }

  echo $counter;

  mysqli_close($conn);


   ?>
  • 请提供您的数据库架构
  • 我确实编辑了我的初始帖子。

标签: php mysql xml


【解决方案1】:

这是您真正想要使用某种 SQL 查询生成器的任务。我将使用 Laravel 的代码发布(未经测试的)代码。您可以选择任何其他,或手动构建查询。 因此,我们所做的就是将每个产品的数据累积在一个临时数组中,并在每次遇到下一个产品时将其推送到数据库。 注意:您的 XML 可能有多个 sizes 用于一种产品。下面的方法将仅使用最后一种方法,因为您没有产品尺寸表。

<?php
use Illuminate\Support\Facades\DB;

$xml = new XMLReader;
$xml->open('XML_URL');

// We will collect single product data here
$product_data = [];
while ($xml->read()) {    

    if ($xml->nodeType === XMLReader::ELEMENT && $xml->name == 'product'){

        // This is the key block
        // For a non-empty product data we insert a new row
        if( !empty( $product_data ) ){

            // Using Laravel query builder.
            // Any other will do the trick, i just dont want to mess
            // with building SQL manually
            DB::table('table')->insert($product_data);

            // Reinit product data with empty array
            $product_data = [];
        }

        $product_data['un_id'] = $xml->getAttribute('id');
        
    }

    if ($xml->nodeType === XMLReader::ELEMENT && $xml->name == 'price')
        $product_data['price'] = $xml->getAttribute('net');

    /*
    ... and so on ...

    I'd recommend making an external map of some sort like:
    [
        'size' => [
            'attribute' => 'iaiext:code_external',
            'target_db_field' => 'ean'
        ]
    ]

    And fill in the product_data using this map

    */    

}

// At this point we might have a non empty product data that was not inserted yet
// coz we will never meet another <product> tag.. just insert what we have:
if( !empty( $product_data ) )
    DB::table('table')->insert($product_data);

【讨论】:

  • 非常感谢您抽出宝贵的时间,但我认为使用这样的框架对于此操作来说太过分了,我到目前为止还缺乏嵌套 xml 节点的经验。能够在表格中显示我需要的数据并且无法将它们插入到 mysql 表格中,这让我感到非常沮丧。
  • 我同意使用框架是一种矫枉过正。您可以使用任何其他允许登陆查询的查询构建库,例如Insert( 'table' )-&gt;values( $product_data )-&gt;execute(),而无需手动构建查询。关键思想是 - 仅在遇到下一个&lt;product&gt; 时执行(或批处理)查询。并在最后一个条目的脚本末尾。
【解决方案2】:

为了回答我的问题,我终于通过 xpath 导入了 XML 结构

  <?xml version="1.0" encoding="UTF-8"?>
  <products currency="EUR">
  <product id="457654754" vat="13.0">
  <price gross="0.09" net="0.07"/>
  <sizes>
    <size id="0"  name="gfdgfdgfdg" panel_name="dfgfdgfdgfd" 
     code_producer="fgdfgfdg"  
     iaiext:code_external="457547547547"  code="354643643643"  weight="4"  
  iaiext:weight_net="10" >
    <stock id="1" quantity="333"/>
    </size>
 </sizes>
 </product>
 </products>

作为

     <?php
     $conn = mysqli_connect("xxx","xxx","xxx","xxx")
      $context  = stream_context_create(array('http' => array('header' => 
  'Accept: 
    application/xml')));
    $xml_file = 'FULL_URL_OF_XML_FILE';
    $xmlsss = file_get_contents($xml_file, false, $context);
    $xml = simplexml_load_string($xmlsss);
    $count = count($xml->xpath('/products/product'));
   for($i = 1; $i <= $count; $i++){
    $id = $xml->xpath('/products/product['.$i.']/@id')[0];
        $stock = $xml->xpath('/products/product['.$i.']/sizes/size/stock/@quantity')[0];
    $price = $xml->xpath('/products/product['.$i.']/price/@net')[0];
    $ean = $xml->xpath('/products/product['.$i.']/sizes/size/@iaiext:code_external')[0];

    $sql = "INSERT INTO table(id,price,quantity,ean) VALUES ('" . $id . "','" 
 . $price . "','" . $stock . "','" . $ean . "')";
  mysqli_query($conn, $sql);
 }
 mysqli_close($conn);
 ?>

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-08-20
    • 2023-03-28
    • 1970-01-01
    • 2023-03-19
    • 2017-12-24
    相关资源
    最近更新 更多