protected function Xml::fetchNextRow in Migrate Plus 8.2
Same name and namespace in other branches
- 8.5 src/Plugin/migrate_plus/data_parser/Xml.php \Drupal\migrate_plus\Plugin\migrate_plus\data_parser\Xml::fetchNextRow()
- 8.3 src/Plugin/migrate_plus/data_parser/Xml.php \Drupal\migrate_plus\Plugin\migrate_plus\data_parser\Xml::fetchNextRow()
- 8.4 src/Plugin/migrate_plus/data_parser/Xml.php \Drupal\migrate_plus\Plugin\migrate_plus\data_parser\Xml::fetchNextRow()
Retrieves the next row of data from the open source URL, populating currentItem.
Overrides DataParserPluginBase::fetchNextRow
File
- src/
Plugin/ migrate_plus/ data_parser/ Xml.php, line 183
Class
- Xml
- Obtain XML data for migration using the XMLReader pull parser.
Namespace
Drupal\migrate_plus\Plugin\migrate_plus\data_parserCode
protected function fetchNextRow() {
$target_element = NULL;
// Loop over each node in the XML file, looking for elements at a path
// matching the input query string (represented in $this->elementsToMatch).
while ($this->reader
->read()) {
if ($this->reader->nodeType == \XMLReader::ELEMENT) {
if ($this->prefixedName) {
$this->currentPath[$this->reader->depth] = $this->reader->name;
if (in_array($this->reader->name, $this->parentElementsOfInterest)) {
$this->parentXpathCache[$this->reader->depth][$this->reader->name][] = $this
->getSimpleXml();
}
}
else {
$this->currentPath[$this->reader->depth] = $this->reader->localName;
if (in_array($this->reader->localName, $this->parentElementsOfInterest)) {
$this->parentXpathCache[$this->reader->depth][$this->reader->name][] = $this
->getSimpleXml();
}
}
if ($this->currentPath == $this->elementsToMatch) {
// We're positioned to the right element path - build the SimpleXML
// object to enable proper xpath predicate evaluation.
$target_element = $this
->getSimpleXml();
if ($target_element !== FALSE) {
if (empty($this->xpathPredicate) || $this
->predicateMatches($target_element)) {
break;
}
}
}
}
elseif ($this->reader->nodeType == \XMLReader::END_ELEMENT) {
// Remove this element and any deeper ones from the current path.
foreach ($this->currentPath as $depth => $name) {
if ($depth >= $this->reader->depth) {
unset($this->currentPath[$depth]);
}
}
foreach ($this->parentXpathCache as $depth => $elements) {
if ($depth > $this->reader->depth) {
unset($this->parentXpathCache[$depth]);
}
}
}
}
// If we've found the desired element, populate the currentItem and
// currentId with its data.
if ($target_element !== FALSE && !is_null($target_element)) {
foreach ($this
->fieldSelectors() as $field_name => $xpath) {
$prefix = substr($xpath, 0, 3);
if (in_array($prefix, [
'../',
'..\\',
])) {
$name = str_replace($prefix, '', $xpath);
$up = substr_count($xpath, $prefix);
$values = $this
->getAncestorElements($up, $name);
}
else {
$values = $target_element
->xpath($xpath);
}
foreach ($values as $value) {
// If the SimpleXMLElement doesn't render to a string of any sort,
// and has children then return the whole object for the process
// plugin or other row manipulation.
if ($value
->children() && !trim((string) $value)) {
$this->currentItem[$field_name] = $value;
}
else {
$this->currentItem[$field_name][] = (string) $value;
}
}
}
// Reduce single-value results to scalars.
foreach ($this->currentItem as $field_name => $values) {
if (count($values) == 1) {
$this->currentItem[$field_name] = reset($values);
}
}
}
}