1

I have a json file like this

{
  "online": false,
  "key": "123",
  "Product": {
    "name": "product name",
    "Id": 12,
  },
}

I have my json migration file

source:
  plugin: url
  data_fetcher_plugin: file
  data_parser_plugin: json
  urls:
    - 'json_path/data.json'
  item_selector: /Product
  fields:
    - name: keyword
      label: 'Keyword'
      selector: name
  ids:
    product_key:
      type: string
  constants:
    vocabulary: tag
process:
  vid: constants/vocabulary
  name: keyword
destination:
  plugin: entity:taxonomy_term

but I am getting the following error.

Drupal\Core\Database\IntegrityConstraintViolationException: SQLSTATE[23000]: Integrity constraint violation: 1048 Column 'name' cannot be null

It means the xpath is not correct.

I have tried with the item_selector: $ and for the keyword selector selector: Product.name but then I am getting this error.

Passed variable is not an array or object

I have tried with item_selector: 0 and item_selector: / but nothing worked.

However when I use the following json.

{
  "online": false,
  "key": "123",
  "Product": [
    {
      "name": "product name",
      "Id": 12,
    }
  ],
}

Notice the [] brackets.

What is the issue? How can I make it work without the [] brackets because I don't have any control on the json to change it.

1 Answer 1

0

The data_parser_plugin: json always expects an array with numeric keys as item_selector, there is no way you can get around this requirement in YAML. If you want to use a single object as item_selector, you have to create your own data_parser_plugin.

I've already had that problem in a previous object and creates my custom plugin and used my custom data_parser_plugin: single_json_object in YAML instead.

file MY_MODULE/src/Plugin/migrate_plus/data_parser/SingleJsonObject.php

<?php

namespace Drupal\MY_MODULE\Plugin\migrate_plus\data_parser;

use Drupal\migrate_plus\Plugin\migrate_plus\data_parser\Json;

/**
 * Obtain JSON data for migration.
 *
 * @DataParser(
 *   id = "single_json_object",
 *   title = @Translation("Single JSON object as root")
 * )
 */
class SingleJsonObject extends Json {

  protected function has_string_keys(array $array) {
    return count(array_filter(array_keys($array), 'is_string')) > 0;
  }

  protected function getSourceData($url) {
    $source_data = parent::getSourceData($url);

    if ($this->has_string_keys($source_data)) {
      $sequential_array = [];
      $sequential_array[] = $source_data;
      $source_data = $sequential_array;
    }

    return $source_data;
  }
}
2
  • what will be the value of the item_selector then? and the keyword selector?
    – Ahmad
    Commented Dec 10, 2020 at 11:42
  • I have used item_selecotr: / and the keyword selector as selector: Product/name and it worked for me with your data parser plugin
    – Ahmad
    Commented Dec 10, 2020 at 12:41

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.