Index: XML.php
===================================================================
RCS file: /repository/pear/Structures_DataGrid/DataGrid/DataSource/XML.php,v
retrieving revision 1.8
diff -u -r1.8 XML.php
--- XML.php 23 Apr 2006 18:45:10 -0000 1.8
+++ XML.php 30 Jun 2006 09:44:09 -0000
@@ -29,6 +29,13 @@
*
* "xpath": XPath to a subset of the XML data.
*
+ * "fieldAttribute": Which Attribute of the XML source should be
+ * used as column field name (only used if the XML source has attributes).
+ *
+ * "labelAttribute": Which Attribute of the XML source should be
+ * used as column label (only used if "generate_columns" is true and the
+ * XML source has attributes).
+ *
* @package Structures_DataGrid
* @author Olivier Guilyardi
* @category Structures
@@ -44,7 +51,13 @@
function Structures_DataGrid_DataSource_XML()
{
parent::Structures_DataGrid_DataSource_Array();
- $this->_addDefaultOptions(array('xpath' => ''));
+ $this->_addDefaultOptions(
+ array(
+ 'xpath' => '',
+ 'fieldAttribute' => null,
+ 'labelAttribute' => null
+ )
+ );
}
/**
@@ -79,7 +92,13 @@
// Instantiate XML_Unserializer Object
$unserializer = &new XML_Unserializer();
$unserializer->setOption('parseAttributes', true);
+ // Set containers for attributes and content (for the case attributes are found)
$unserializer->setOption('attributesArray', 'attributes');
+ $unserializer->setOption('contentName', 'content');
+ // Use fieldAttribute as item key, if fieldAttribute option set
+ if (!is_null($this->_options['fieldAttribute'])) {
+ $unserializer->setOption('keyAttribute', $this->_options['fieldAttribute']);
+ }
// Unserialize the XML Data
$test = $unserializer->unserialize($xml, false);
@@ -98,16 +117,61 @@
return PEAR::raiseError('Unable to bind the xml data. '.
'You may want to set the \'xpath\' option.');
}
-
- $this->_ar[] = $row;
+ $this->_ar[] = $this->_processRow($row);
}
if ($this->_ar and !$this->_options['fields']) {
- $this->setOptions(array('fields' => array_keys($this->_ar[0])));
+ $this->setOption('fields', array_keys($this->_ar[0]));
}
return true;
}
+
+ /**
+ * Process XML row
+ *
+ * @access private
+ * @param array $row Row from unserializer data array
+ * @param string $keyPrefix Prepended to key, for recursive processing
+ * @return array of form: array($field1 => $value1, $field2 => $value2, ...)
+ */
+ function _processRow($row, $keyPrefix='')
+ {
+ $rowProcessed = array();
+ foreach ($row as $item => $info) {
+ $itemKey = $keyPrefix.$item;
+ switch (true) {
+ // Item has no attributes and unique tag name
+ case !is_array($info):
+ $rowProcessed[$itemKey] = $info;
+ break;
+ // Items with non-unique tag names, or fieldAttribute option is null
+ // Process array elements recursively as separate items
+ case !isset($info['attributes']):
+ $rowProcessed += $this->_processRow($info, $itemKey);
+ break;
+ // Attributes found: field attribute is already in item key
+ // extract label if option set and $this->_options['labels'] is empty
+ case !$this->_options['labels'] &&
+ !is_null($this->_options['labelAttribute']):
+ if (isset($info['attributes'][$this->_options['labelAttribute']])) {
+ $labels[$itemKey] = $info['attributes'][$this->_options['labelAttribute']];
+ }
+ else {
+ $labels[$itemKey] = $itemKey;
+ }
+ // no break here; we need the content!
+ default:
+ $rowProcessed[$itemKey] = isset($info['content'])
+ ? $info['content'] : '';
+ }
+ }
+ // Set labels if extracted
+ if (!$this->_options['labels'] && isset($labels)) {
+ $this->setOption('labels', $labels);
+ }
+ return $rowProcessed;
+ }
}