diff --git a/src/Plugin/migrate_plus/data_parser/Xml.php b/src/Plugin/migrate_plus/data_parser/Xml.php index 2737850aa365960a1e8824046885d7cc5ef09c4f..2eb4314296e3192ddda0000bfb2e323ec1502cb1 100644 --- a/src/Plugin/migrate_plus/data_parser/Xml.php +++ b/src/Plugin/migrate_plus/data_parser/Xml.php @@ -257,9 +257,12 @@ class Xml extends DataParserPluginBase { } } } - // Reduce single-value results to scalars. + // Reduce single-value arrays to scalars. foreach ($this->currentItem as $field_name => $values) { - if (count($values) == 1) { + // We cannot use reset for SimpleXmlElement because it might have + // attributes that are not counted. Get the first value, even if there + // are more values available. + if (is_array($values) && count($values) == 1) { $this->currentItem[$field_name] = reset($values); } } diff --git a/tests/data/xml_data_parser.xml b/tests/data/xml_data_parser.xml new file mode 100644 index 0000000000000000000000000000000000000000..cdcae9fc451481bce98760e35c4224d67734a969 --- /dev/null +++ b/tests/data/xml_data_parser.xml @@ -0,0 +1,35 @@ +<?xml version="1.0" encoding="utf-8"?> +<persons> + <person> + <id>1</id> + <name>Elizabeth</name> + <children> + <child age="8"> + <name>Elizabeth Junior</name> + <name>Jane</name> + </child> + </children> + </person> + <person> + <id>2</id> + <name>George</name> + <children> + <child> + <name>George Junior</name> + <age>10</age> + </child> + </children> + </person> + <person> + <id>3</id> + <name>Peter</name> + <children> + <child> + <name>James</name> + </child> + <child> + <name age="6">Lucy</name> + </child> + </children> + </person> +</persons> diff --git a/tests/src/Kernel/Plugin/migrate_plus/data_parser/XmlTest.php b/tests/src/Kernel/Plugin/migrate_plus/data_parser/XmlTest.php new file mode 100644 index 0000000000000000000000000000000000000000..348d3326cf2a6cc1bd946acee797a0e2dbb100fb --- /dev/null +++ b/tests/src/Kernel/Plugin/migrate_plus/data_parser/XmlTest.php @@ -0,0 +1,63 @@ +<?php + +namespace Drupal\Tests\migrate_plus\Kernel\Plugin\migrate_plus\data_parser; + +use Drupal\KernelTests\KernelTestBase; + +/** + * Test of the data_parser Xml migrate_plus plugin. + * + * @group migrate_plus + */ +class XmlTest extends KernelTestBase { + + public static $modules = ['migrate', 'migrate_plus']; + + /** + * Tests retrieving single value from element with attributes. + * + * @throws \Drupal\Component\Plugin\Exception\PluginException + * @throws \Exception + */ + public function testSingleValue() { + $path = $this->container + ->get('module_handler') + ->getModule('migrate_plus') + ->getPath(); + $fileUrl = $path . '/tests/data/xml_data_parser.xml'; + $conf = [ + 'plugin' => 'url', + 'data_fetcher_plugin' => 'file', + 'data_parser_plugin' => 'xml', + 'destination' => 'node', + 'urls' => [$fileUrl], + 'ids' => ['id' => ['type' => 'integer']], + 'fields' => [ + [ + 'name' => 'id', + 'label' => 'Id', + 'selector' => 'id', + ], + [ + 'name' => 'child', + 'label' => 'child', + 'selector' => 'children/child', + ], + ], + 'item_selector' => '/persons/person', + ]; + + /** @var \Drupal\migrate_plus\DataParserPluginManager $plugin_manager */ + $plugin_manager = $this->container->get('plugin.manager.migrate_plus.data_parser'); + $parser = $plugin_manager->createInstance('xml', $conf); + + $names = []; + foreach ($parser as $item) { + $names[] = (string) $item['child']->name; + } + + $expectedNames = ['Elizabeth Junior', 'George Junior', 'Lucy']; + $this->assertEquals($expectedNames, $names); + } + +}