Hello,

I've identified a small bug in the next funcition of the MigrateXMLReader class, which causes missing records when parsing xml migration sources. It come up when the last element in a record is empty and closed in the starting tag, like the field element in record 2 of this example:

<records>
  <record>
    <id>1</id>
    <field>something</field>
  </record>
  <record>
    <id>2</id>
    <field />
  </record>
  <record>
    <id>3</id>
    <field>something</field>
  </record>

In this example, record 3 would be skipped by the reader, due to the way that elements are unset in the currentPath array:

      elseif ($this->reader->nodeType == XMLREADER::END_ELEMENT) {
        // Trim currentPath as we exit each element
        unset($this->currentPath[$this->reader->depth]);
      }

When parsing record 2, it would unset the record element at depth 1 of the currentPath array, but leave the field element at depth 2, since it never encountered a close tag for that element. Then when the read() loop iterates again, it has that vestigial depth 2 element in the currentPath array, and it fails to match the elementsToMatch array, and record 3 is not added to the DOM.

Comments

mikemccaffrey’s picture

StatusFileSize
new750 bytes

The attached patch replaces the code above with a version that not only unsets the depth of element that is being closed, but also any deeper elements in the array that did not have an explicit close tag.

      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]);
          }
        }
      }
mikeryan’s picture

Status: Needs review » Fixed

Committed to D6 and D7, thanks!

Status: Fixed » Closed (fixed)

Automatically closed -- issue fixed for 2 weeks with no activity.