In 7.x-2.6 you could use XPath to target Dates and the filter would receive an array of 3 arrays where the child elements are key/value pairs (ie StartDate, EndDate, etc). This same XPath in 7.x-2.7 sends an empty value to my filter function. Is there any way to do the same thing with 7.x-2.7?

<?xml version="1.0" encoding="utf-8"?>
<CalendarOfEvents>
  <Event>
    <Dates>
      <Item>
        <StartDate>11/29/2013</StartDate>
        <EndDate>11/29/2014</EndDate>
        <StartTime>09:00:00 AM</StartTime>
        <EndTime>05:00:00 PM</EndTime>
      </Item>
      <Item>
        <StartDate>12/6/2013</StartDate>
        <EndDate>12/6/2014</EndDate>
        <StartTime>09:00:00 AM</StartTime>
        <EndTime>05:00:00 PM</EndTime>
      </Item>
      <Item>
        <StartDate>12/13/2013</StartDate>
        <EndDate>12/13/2014</EndDate>
        <StartTime>09:00:00 AM</StartTime>
        <EndTime>05:00:00 PM</EndTime>
      </Item>
    </Dates>
  </Event>
</CalendarOfEvents>

Comments

Sorin Sarca’s picture

Hi,
could you post your xpath?

blake.thompson’s picture

Issue summary: View changes

Parent item xpath is //Event, field xpath is Dates

Sorin Sarca’s picture

Ok, I don't know if this is a good fix but you should try it.
Open feed_import.inc.php file and find the getXpathValue function (around line 410). Replace it with this function:

public static function getXpathValue(&$item, $xpath) {
    // Get values and handle xpath exceptions.
    try {
      $values = $item->xpath($xpath);
    }
    catch (Exception $e) {
      return NULL;
    }

    // Xpath gave no values return null.
    if (!$values) {
      return NULL;
    }

    // Get the number of values.
    $count = count($values);
    $i = -1;
    while (++$i < $count) {
      if (!$values[$i]->count()) {
        // Get each value.
        $values[$i] = (string) $values[$i][0];
      }
    }

    // Return value or an array of values.
    return $count == 1 ? $values[0] : $values;
  }
blake.thompson’s picture

Thanks, that got it a little closer. I made a change in the while statement which will convert a SimpleXMLElement into an array. I believe I read this will only use UTF-8 encoding, so if someone's data is using another encoding this won't work for them. Otherwise I think a recursive conversion function would be necessary, or each XML element would have to be handled in its own filter function.

Also, if someone was targeting the xpath equivalent of Dates as I was (where in 7.x-2.6 targeting Dates or Dates/Item would have yielded the same thing), this will now require the xpath to target Dates/Item.

<?php
public static function getXpathValue(&$item, $xpath) {
    // Get values and handle xpath exceptions.
    try {
      $values = $item->xpath($xpath);
    }
    catch (Exception $e) {
      return NULL;
    }

    // Xpath gave no values return null.
    if (!$values) {
      return NULL;
    }

    // Get the number of values.
    $count = count($values);
    $i = -1;
    while (++$i < $count) {
      if (!$values[$i]->count()) {
        // Get each value.
        $values[$i] = (string) $values[$i][0];
      } else {
        $values[$i] = json_decode(json_encode((array) $values[$i]), 1);
      }
    }

    // Return value or an array of values.
    return $count == 1 ? $values[0] : $values;
  }
?>
Sorin Sarca’s picture

Well, the filter function should handle any encoding issues.
Also, this line

$values[$i] = json_decode(json_encode((array) $values[$i]), 1);

should have only an array cast (nested items won't be converted to an array, but again, the filter function should handle them).

$values[$i] = (array) $values[$i];

Maybe this fix needs more test in order to release it.
As the project page says, I'm looking for maintainers, and if you want (and you are interested) I can add you as maintainer.

blake.thompson’s picture

<?php
$values[$i] = json_decode(json_encode((array) $values[$i]), 1);
?>

Will convert the array and anything nested into an associative array, otherwise I'd have to go back through each of my filter functions that expect arrays and do the same thing, or a string conversion for each value. This just seemed easier for my use case. I can see why just typing it to an array to let filter functions handle the data would be more appropriate though.

With this change and updating my xpath where necessary everything is working as expected importing about 1500 nodes.

I'd consider helping out as a maintainer, I haven't helped maintain a module before so if you wanted to contact me and let me know how that'd work that'd be great.

Sorin Sarca’s picture

Status: Active » Closed (won't fix)

Since for version 2 is approaching end of life, I'll focus more on version 3.
Anyway, if you still want and have time to help developing this module just contact me.