xml-wrangler icon indicating copy to clipboard operation
xml-wrangler copied to clipboard

Add recursively converting an element into values

Open marcoboers opened this issue 1 year ago • 0 comments

This PR provides a convenient way to convert an Element into values. This allows to first traverse elements and check their attributes after which you can easily convert it to a nested array which can be conveniently used by dot notation.

A usecase:

<breakfast_menu>
  <food soldOut="true" bestSeller="true">
    <id>50620426-c0ea-42f0-bdda-09524cecdb43</id>
    <name>Belgian Waffles</name>
    <price>$5.95</price>
    <description>Two of our famous Belgian Waffles with plenty of real maple syrup</description>
    <nutritionalValue>
      <calories>
        <value>650</value>
        <unit>kcal</unit>
      </calories>
      <protein>
        <value>10</value>
        <unit>g</unit>
      </protein>
      <carbs>
        <value>30</value>
        <unit>g</unit>
      </carbs>
      <salt>
        <value>500</value>
        <unit>mg</unit>
      </salt>
    </nutritionalValue>
  </food>
  <food soldOut="false" bestSeller="false">
    <id>f3b1d170-fcfa-4ac6-a419-b9bef69ef887</id>
    <name>Strawberry Belgian Waffles</name>
    <price>$7.95</price>
    <description>Light Belgian waffles covered with strawberries and whipped cream</description>
    <nutritionalValue>
      <calories>
        <value>700</value>
        <unit>kcal</unit>
      </calories>
      <protein>
        <value>10</value>
        <unit>g</unit>
      </protein>
      <carbs>
        <value>40</value>
        <unit>g</unit>
      </carbs>
      <salt>
        <value>500</value>
        <unit>mg</unit>
      </salt>
    </nutritionalValue>
  </food>
  <food soldOut="false" bestSeller="true">
    <id>b99beb27-f3b5-43f1-99d7-80b9110c70d0</id>
    <name>Berry-Berry Belgian Waffles</name>
    <price>$8.95</price>
    <description>Light Belgian waffles covered with an assortment of fresh berries and whipped cream</description>
    <nutritionalValue>
      <calories>
        <value>900</value>
        <unit>kcal</unit>
      </calories>
      <protein>
        <value>10</value>
        <unit>g</unit>
      </protein>
      <carbs>
        <value>45</value>
        <unit>g</unit>
      </carbs>
      <salt>
        <value>500</value>
        <unit>mg</unit>
      </salt>
    </nutritionalValue>
  </food>
</breakfast_menu>
$reader = XmlReader::fromPsrResponse($response);
$foods = $reader->element('food')->lazy()
foreach ($foods as $food) {
    if (! $food->getAttribute('soldOut')) {
        $foodValues = $food->values();
        Product::updateOrCreate([
            'uuid' = data_get($foodValues, 'id')
        ], [
            'title' = data_get($foodValues, 'name'),
            'description' = data_get($foodValues, 'description'),
            'calories' = data_get($foodValues, 'nutritionalValue.calories.value'), // access deeper element using dot notation
            'salt' = data_get($foodValues, 'nutritionalValue.salt.value') . data_get($foodValues, 'nutritionalValue.salt.unit') 
        ]);
    }
}

marcoboers avatar Aug 09 '24 10:08 marcoboers