Actions

User

Chris Davenport/JData/Adapters/XML

From Joomla! Documentation

< User:Chris Davenport‎ | JData
Revision as of 04:45, 5 December 2011 by Chris Davenport (Talk | contribs)

(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)

JDataAdapterXml is a JData adapter that can read and write data in XML format. In input mode it uses a stream parser and so is capable of processing very large XML files with minimal impact on memory usage.

$config = array(
  'mode' => 'input',
);
$adapter = JDataAdapter::getInstance( 'xml', 'JDataAdapter', $config );

Contents

Configuration

The following configuration variables are available:-

Key Value Default
mode is either "input" or "output" depending on whether the adapter is reading or writing XML data respectively. input
filename is only relevant in input mode and specifies the filename to read XML data from.

Examples

Example 1: Processing XML input data

Important note: In input mode you do not need to specify a connector because the XML stream parser opens a file directly.

For example, suppose you have the following XML data in file "testfile.xml":

<?xml version="1.0" ?>
<root>
  <instance>
    <key>1</key>
    <title>One</title>
    <description>The first</description>
  </instance>
 
  <instance>
    <key>2</key>
    <title>Two</title>
    <description>The second</description>
  </instance>
 
  <instance>
    <key>3</key>
    <title>Three</title>
    <description>The Third</description>
  </instance>
</root>

Then you could use code like this

$config = array(
  'mode' => 'input',
  'filename' => 'testfile.xml',
);
$inputAdapter = JDataAdapter::getInstance( 'xml', 'JDataAdapter', $config );
$handler = JDataHandler::getInstance( 'xml', 'test' )
  ->attach( $inputAdapter )
  ->attach( $outputAdapter, $outputConnector )
  ->execute()
  ;

If your handler extension class comprises

class TestXml extends JDataHandlerSimple
{
    public function processFieldStartKey( JDataAdapter $field )
    {
        $this->addField( $field );
        return true;
    }
 
    public function processFieldStartTitle( JDataAdapter $field )
    {
        $this->addField( $field );
        return true;
    }
 
    public function processFieldStartDescription( JDataAdapter $field )
    {
        $this->addField( $field );
        return true;
    }
 
    public function processFieldEndInstance( JDataAdapter $field )
    {
        return false;
    }
}

then all fields in the XML would be parsed into data records as expected.

Notice how the processFieldEndInstance method is used to define to determine where the data record ends. It is especially important when processing XML files to use this mechanism to break the data into individual records.

Example 2: Dealing with XML attributes

This example is similar to the previous one, but the key is contained in an attribute instead of a separate element.

<?xml version="1.0" ?>
<root>
  <instance key="1">
    <title>One</title>
    <description>The first</description>
  </instance>
 
  <instance key="2">
    <title>Two</title>
    <description>The second</description>
  </instance>
 
  <instance key="3">
    <title>Three</title>
    <description>The third</description>
  </instance>
</root>

The handler extension class then becomes

class TestXml extends JDataHandlerSimple
{
    public function processFieldStartInstance( JDataAdapter $field )
    {
        $field->name    = 'key';
        $field->value    = $field->attribs['key'];
        $this->addField( $field );
 
        return true;
    }
 
    public function processFieldStartTitle( JDataAdapter $field )
    {
        $this->addField( $field );
        return true;
    }
 
    public function processFieldStartDescription( JDataAdapter $field )
    {
        $this->addField( $field );
        return true;
    }
 
    public function processFieldEndInstance( JDataAdapter $field )
    {
        return false;
    }
}

thus transforming an attribute in the XML tag into a separate field in the handler's record buffer.

Example 3: Output data in XML format

$outputAdapter = JDataAdapter::getInstance( 'xml', 'JDataAdapter', array( 'mode' => 'output' ) );
$outputConnector = JDataConnector::getIntance( 'file', 'JDataConnector', array( 'filename' => 'test.xml' ) );
$handler = JDataHandler::getInstance( 'xml', 'test' )
  ->attach( $inputAdapter, $inputConnector )
  ->attach( $outputAdapter, $outputConnector )
  ->execute()
  ;

Note that you must use a connector in the handler attach method call. The JDataConnectorFile connector is used in the example above.

Currently JDataAdapterXml does not support output of fields as XML attributes.