3

In the Migrate module I noticed that one reason I could not import an XML file was because it contained namespaces. Removing namespaces from the XML file and Migrate class allowed me to import the content without issue.

In trying to fix this issue I came across this post which brought me to this patch for the xml.inc file (used to import xml sources) in the Migrate module. Unfortunately it was for an outdated version of the module so I had to manually apply it.

The patch does not seem to work as I still get this error when attempting to migrate (the same error I was getting before applying the patch):

Migration failed with source plugin exception: Passed variable is not an array or object, using empty array instead

I think I have tracked down where the issue is appearing in the xml.inc code, as this function, &xml, does not output $this->currentXml which should be a simplexml_load_file:

/**
   * Load and return the xml from currentUrl.
   *
   * @return SimpleXMLElement
   */
  public function &xml() {
    if (!empty($this->currentUrl)) {
      dpm('start grab url/xml');
      dpm($this->currentUrl);//it is grabbing this url ok
      $this->currentXml = simplexml_load_file($this->currentUrl);
      dpm($this->currentXML);//it is not loading the file properly it seems
      dpm('end grab url/xml');
      if (!$this->currentXml) {
        Migration::displayMessage(t(
          'Loading of !currentUrl failed:',
          array('!currentUrl' => $this->currentUrl)
        ));
        foreach (libxml_get_errors() as $error) {
          Migration::displayMessage(self::parseLibXMLError($error));
        }
      }
      else {
        dpm('register namespace');
        dpm($this->registerNamespaces($this->currentXml)); // this then fails
                                                           // to load since
                                                           // $this->currentXml 
                                                           // is not populated, 
                                                           // which is most 
                                                           // likely generating the error
        dpm('endr egister namespace');
      }
    }
    return $this->currentXml;
  }

Here is the output when migration is run: output with dpm

Is there something that would be stopping a simple php function such as simplexml_load_file to run here? Or could this possibly not even be the issue? There is currently an open issue with the Migrate module for this issue, though there is not much activity on it.

1 Answer 1

2

A few things had to be changed.

public function &xml() {
    if (!empty($this->currentUrl)) {

      // $this->currentXml = simplexml_load_file($this->currentUrl);

      // simplexml_load_file wasn't explicit enough, change to file_get_contents
      // then explicitly call it a new SimpleXmlElement.

      $xml = file_get_contents($this->currentUrl);
      $this->currentXml = new SimpleXmlElement($xml);

      if (!$this->currentXml) {
        Migration::displayMessage(t(
          'Loading of !currentUrl failed:',
          array('!currentUrl' => $this->currentUrl)
        ));
        foreach (libxml_get_errors() as $error) {
          Migration::displayMessage(self::parseLibXMLError($error));
        }
      }
      else {
        $this->registerNamespaces($this->currentXml);
      }
    }

    return $this->currentXml;
  }

However, the major issue was this function in xml.inc:

protected function getElementValue($itemXML, $xpath) {
    $value = NULL;
    if ($itemXML) {
      $result = $itemXML->xpath($xpath);
      if ($result)
        $value = (string)$result[0];
    }
    return $value;
  }

The if($itemXML) needs to be changed to if($itemXML->asXML()), like so:

protected function getElementValue($itemXML, $xpath) {
    $value = NULL;
    if ($itemXML->asXML()) {
      $result = $itemXML->xpath($xpath);
      if ($result)
        $value = (string)$result[0];
    }
    return $value;
  }

After applying the patch manually and changing the simplexml_load_file and the if statement in the above functions, the import works successfully with namespaces.

I re-rolled the patch mentioned earlier with my changes: https://drupal.org/comment/8260027#comment-8260027

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.