4

Currently the xml feed looks something like this

<hotel>
    <hotel_facilities>
        <facility>Gym</facility>
        <facility>Restaurant</facility>
        <facility>Bar</facility>
    </hotel_facilities>
...
</hotel>

I've trying to import all the facilities as taxonomy terms using the Feeds XPath Parser but I am only able to import a single facility. I'm not sure if the module supports this. What currently happens when I set the context to hotel and the xpath query as hotel_facilities/facility it results in the error:

SQLSTATE[42000]: Syntax error or access violation: 1064 You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ' 'Restaurant', 'Bar'' at line 1

If I use the query: hotel_facilities/facility[1] it returns and inputs the term into my taxonomy vocabulary, but I require all the terms to be added.

Is there a query/module or setting that I need to run; or is this a limitation of the Feeds/Feeds XPath Parser parser modules?

4 Answers 4

1

Feeds Tamper will sort this out (I know this for a fact, as I've done this in the last week).

Set your query to hotel_facilities/facility which will return a comma separated list of facilities (you won't see this array as you'll be exploding it. Feel free to dpm() it though). Using Feeds Tamper, you can explode this array.

Go to your feed, and there will be a "Tamper" menu item at the top. If you click this, and then go down whatever xpathparser if importing these facilities. Then click Add plugin and find the explode plugin (you can find it under List)

Feeds tamper add plugin UI

Don't forget to set your Feeds mapping to Search taxonomy terms by: Term Name and check the "Auto create" checkbox.

0

You have to change the base path to /hotel/hotel_facilites/facility

Then it should work.

0

Chapabu has the right answer. I went a step further and made a Tamper plugin.

When I needed to set this up myself, I ended up having to add 3 filters to make it work (remove the xml tags, trim content, & drop empty elements). Since I have ~8 similar fields that would all need the same filters, I just wrote up a simple filter for Tamper that does this for me:

Copy this code and add it to sites/all/modules/contrib/feeds_tamper/plugins/xml_explode.inc. You can then select it from from the list of Tamper plugins. Read the notes on this filter for help.

<?php

/**
 * @file
 * Return an array of text from a set of XML nodes.
 */

$plugin = array(
  'form' => 'feeds_tamper_xml_explode_form',
  'callback' => 'feeds_tamper_xml_explode_callback',
  'validate' => 'feeds_tamper_xml_explode_validate',
  'name' => 'Explode XML',
  'multi' => 'direct',
  'category' => 'List',
);

function feeds_tamper_xml_explode_form($importer, $element_key, $settings) {
  $form = array();
  $form['info'] = array(
    '#markup' => t('In order for this to work, make sure you do these things:'
      . '<ul>'
      . '  <li>Write your xpath value to the parent followed by "\*" (eg <code>"Grandparent\Parent\*"</code>)</li>'
      . '  <li>Parse this node as "raw" xml (See <a href="http://goo.gl/cTv6Sc">http://goo.gl/cTv6Sc</a>)</li>'
      . '  <li>Make sure the xml node is only one level deep.</li>'
      . '</ul>'
      . '<b>Note</b>: This plugin is not intended for production.'),
  );
  return $form;
}

function feeds_tamper_xml_explode_callback($result, $item_key, $element_key, &$field, $settings, $source) {
  $out = array();

  if(is_array($field)){
    foreach($field as $k => $string){
      $subject = new SimpleXMLElement($string);
      $out[] = trim( (string)$subject );
    }
  }

  $field = $out;
}
0

I recently found a way to achieve a goal very similar to this. Refer my post here if someone else finds a solution for this.

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.