'Keep only specific nodes from xml with php and save it in another xml file

I have an xml feed (feed.xml) as:

<?xml version="1.0" encoding="UTF-8"?>
<items>
 <item>
  <itemcode>432432</itemcode>
  <title>test</title>
  <platform>test</platform>
  <genre>test</genre>
  <pegi>test</pegi>
  <price_eur>16</price_eur>
  <ean>436436436436</ean>
  <release_date>2019-09-06</release_date>
  <image_url>testtest</image_url>
  <stock>41</stock>
  <manufacturer>test</manufacturer>
  <oem/>
  <weight_g>100.0</weight_g>
  <length_mm>170.0</length_mm>
  <width_mm>135.0</width_mm>
  <height_mm>15.0</height_mm>
</item>
 .....
</items>

And I need only 3 of those nodes (itemcode, stock, price_eur) that I insert them into a mysql database as:

  mysqli_query($conn, $query);
  $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);
  //print_r($arrFeeds);
   }


  $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);

How can i load the initial feed.xml and save it with another name only keeping those 3 nodes itemcode, stock, price_eur before importing them into the database so the xml file is smaller and the whole process faster?



Solution 1:[1]

Modifying the XML will only speed up the XML parsing (DOMDocument::load()) slightly. You still need to spend the additional time for the transformation if separately.

I suggesting checking the syntax for mass inserts to reducing the amount of insert queries.

INSERT INTO table_name
  VALUES 
    (...), 
    (...), 
    (...)

Or use MySQL LOAD XML

LOAD XML
  INFILE 'file_name'
  INTO TABLE table_name
  ...

However building a new XML file can be done by copying the nodes.

$source = new DOMDocument();
$source->load('feed.xml');
$xpath = new DOMXpath($source);

$target = new DOMDocument();
// copy items element without descendants
$target->appendChild(
    $targetItems = $target->importNode($source->documentElement, FALSE)
);

foreach ($xpath->evaluate('/items/item') as $sourceItem) {
    // copy item element without descendants
    $targetItems->appendChild(
        $targetItem = $target->importNode($sourceItem, FALSE)
    ); 
    // fetch nodes filtered by name
    foreach($xpath->evaluate('*[self::itemcode or self::stock or self::price_eur]') as $sourceChild) {
        // copy item element with descendants
        $targetItem->appendChild(
          $target->importNode($sourceChild, TRUE)
        );
    } 
}

$target->save('feed_reduced.xml');

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 ThW