View source  
  <?php
require_once 'views_data_export_exporter.inc';
require_once 'ViewsDataExportExporterUserConfigurationInterface.inc';
class ViewsDataExportExporterXML extends ViewsDataExportExporter implements ViewsDataExportExporterUserConfigurationInterface {
  
  function __construct($options) {
    
    $definition = $this
      ->option_definition();
    foreach ($definition as $option_name => $properties) {
      if (!isset($options[$option_name])) {
        $options[$option_name] = $properties['default'];
      }
    }
    $options['no_entity_encode'] = array_filter($options['no_entity_encode']);
    $options['cdata_wrapper'] = array_filter($options['cdata_wrapper']);
    $this->options = $options;
    parent::__construct($options);
  }
  
  function supports_hide_if_empty() {
    return TRUE;
  }
  
  function option_definition() {
    $definition = array();
    $definition['transform'] = array(
      'default' => TRUE,
      'translatable' => FALSE,
    );
    $definition['transform_type'] = array(
      'default' => 'dash',
      'translatable' => FALSE,
    );
    $definition['root_node'] = array(
      'default' => 'root',
      'translatable' => FALSE,
    );
    $definition['item_node'] = array(
      'default' => 'item',
      'translatable' => FALSE,
    );
    $definition['no_entity_encode'] = array(
      'default' => array(),
      'translatable' => FALSE,
    );
    $definition['cdata_wrapper'] = array(
      'default' => array(),
      'translatable' => FALSE,
    );
    return $definition;
  }
  
  function options_form(&$form, &$form_state, $field_labels) {
    $form['transform'] = array(
      '#type' => 'checkbox',
      '#title' => t('Transform spaces'),
      '#default_value' => $this->options['transform'],
      '#description' => t('Transform spaces to valid XML in field labels (spaces create invalid XML markup). Note that invalid XML tag characters will always be converted.'),
    );
    $form['transform_type'] = array(
      '#type' => 'select',
      '#title' => t('Transform type'),
      '#default_value' => $this->options['transform_type'],
      '#options' => array(
        'dash' => t('Dash'),
        'underline' => t('Underline'),
        'camel' => t('camelCase'),
        'pascal' => t('PascalCase'),
      ),
      '#process' => array(
        'ctools_dependent_process',
      ),
      '#dependency' => array(
        'edit-style-options-transform' => array(
          TRUE,
        ),
      ),
    );
    $form['root_node'] = array(
      '#type' => 'textfield',
      '#title' => t('Root node'),
      '#default_value' => $this->options['root_node'],
      '#description' => t('The XML tag for the root node.'),
    );
    $form['item_node'] = array(
      '#type' => 'textfield',
      '#title' => t('Item node'),
      '#default_value' => $this->options['item_node'],
      '#description' => t('The XML tag for an item node.'),
    );
    if (!empty($field_labels)) {
      if (empty($options['no_entity_encode'])) {
        $options['no_entity_encode'] = array();
      }
      $form['no_entity_encode'] = array(
        '#type' => 'checkboxes',
        '#title' => t('Disable encoding of XML entities for these fields'),
        '#options' => $field_labels,
        '#default_value' => $this->options['no_entity_encode'],
        '#description' => t('If checked field contents will be outputted ' . '<em>without encoding</em> of XML entities. This is ' . 'useful when when used in conjunction with a field ' . 'formatter that outputs properly formatted and ' . 'encoded XML data.'),
      );
      if (empty($options['cdata_wrapper'])) {
        $options['cdata_wrapper'] = array();
      }
      $form['cdata_wrapper'] = array(
        '#type' => 'checkboxes',
        '#title' => t('Field values to wrap using CDATA'),
        '#options' => $field_labels,
        '#default_value' => $this->options['cdata_wrapper'],
        '#description' => t('If checked the fields content will be wrapped using the CDATA tag.'),
      );
    }
  }
  
  function options_submit(&$form, &$form_state) {
    if (isset($form_state['values']['style_options']['no_entity_encode'])) {
      
      $form_state['values']['style_options']['no_entity_encode'] = array_filter($form_state['values']['style_options']['no_entity_encode']);
    }
    if (isset($form_state['values']['style_options']['cdata_wrapper'])) {
      
      $form_state['values']['style_options']['cdata_wrapper'] = array_filter($form_state['values']['style_options']['cdata_wrapper']);
    }
  }
  
  function add_row(&$file_handle, $data, $row_count, $field_titles) {
    
    $writer = new XMLWriter();
    $writer
      ->openMemory();
    $writer
      ->setIndent(TRUE);
    $writer
      ->setIndentString("  ");
    
    $null_file = NULL;
    $this
      ->bof($null_file, $writer);
    $writer
      ->writeElement('bluff', 'content');
    
    $writer
      ->flush();
    
    $writer
      ->startElement($this->options['item_node']);
    
    $this
      ->array_to_xml($writer, $data, $file_handle, $field_titles);
    
    $writer
      ->endElement();
    
    $output = $writer
      ->outputMemory(TRUE);
    
    
    fwrite($file_handle, $output);
  }
  function array_to_xml(&$writer, $array, &$file_handle, $field_titles) {
    $key_open = false;
    foreach ($array as $key => $value) {
      
      $clean_tag = $this
        ->_clean_tag_from_key($key, $field_titles);
      
      if (is_array($value)) {
        
        $writer
          ->startElement($clean_tag);
        $key_open = true;
        
        $this
          ->array_to_xml($writer, $value, $file_handle, $field_titles);
      }
      else {
        
        if (in_array($key, $this->options['no_entity_encode'], TRUE)) {
          
          $value_to_write = $value;
          
          $writer
            ->startElement($clean_tag);
          
          $writer
            ->writeRaw($value_to_write);
          
          $writer
            ->endElement();
        }
        else {
          if (in_array($key, $this->options['cdata_wrapper'], TRUE)) {
            
            $value_to_write = $value;
            
            $writer
              ->startElement($clean_tag);
            
            $writer
              ->writeCData($value_to_write);
            
            $writer
              ->endElement();
          }
          else {
            
            $value_to_write = htmlspecialchars($value);
            
            $writer
              ->writeElement($clean_tag, $value_to_write);
          }
        }
      }
      
      if ($key_open) {
        $writer
          ->endElement();
        $key_open = false;
      }
    }
  }
  function _clean_tag_from_key($key, $field_titles) {
    
    if (isset($field_titles[$key])) {
      $key = $field_titles[$key];
    }
    
    if ($key == '0') {
      $key = 'data';
    }
    else {
      if (is_numeric($key)) {
        $key = 'data';
        
      }
      else {
        if (!isset($key) || $key == '') {
          $key = 'no-name';
        }
      }
    }
    
    if (isset($this->options['transform']) && $this->options['transform'] == true) {
      
      switch ($this->options['transform_type']) {
        case 'dash':
          $key = str_replace(' ', '-', $key);
          break;
        case 'underline':
          $key = str_replace(' ', '_', $key);
          break;
        case 'camelCase':
          $key = ucwords($key);
          $key = lcfirst($key);
          $key = str_replace(' ', '', $key);
          break;
        case 'PascalCase':
          $key = ucwords($key);
          $key = str_replace(' ', '', $key);
          break;
      }
    }
    $clean_tag = $this
      ->clean_xml_tag($key);
    return $clean_tag;
  }
  
  function get_headers($filename) {
    $headers = array();
    $headers['Content-Type'] = 'application/force-download';
    $headers['Pragma'] = 'public';
    $headers['Cache-Control'] = 'max-age=0';
    return $headers;
  }
  
  function bof(&$file_handle = null, &$writer = null) {
    
    if (is_null($writer)) {
      $writer = new XMLWriter();
      $writer
        ->openMemory();
      $writer
        ->setIndent(TRUE);
      $writer
        ->setIndentString("  ");
    }
    $writer
      ->startDocument("1.0", "UTF-8");
    $writer
      ->startElement($this->options['root_node']);
    $writer
      ->text('');
    
    if (!is_null($file_handle)) {
      fwrite($file_handle, $writer
        ->outputMemory(TRUE) . PHP_EOL);
    }
  }
  
  function eof(&$file_handle, $row_count, $col_count) {
    
    $writer = new XMLWriter();
    $writer
      ->openMemory();
    $writer
      ->setIndent(TRUE);
    $writer
      ->setIndentString("  ");
    $writer
      ->startDocument("1.0", "UTF-8");
    $writer
      ->startElement($this->options['root_node']);
    $writer
      ->writeElement('bluff', 'empty');
    $writer
      ->flush();
    $writer
      ->endElement();
    
    fwrite($file_handle, $writer
      ->outputMemory(TRUE));
  }
  
  function post_process(&$results) {
  }
  
  function options_validate(&$form, &$form_state) {
  }
}