Logo Search packages:      
Sourcecode: fibusql version File versions  Download package

parsexml.inc

<?php
/*
    FibuSQL 0.4.1  -  (c) 2003 Martin Pitt <martin@piware.de>

    This software is protected by the GNU General Public License (see
    file COPYING).
    
    Backend module: XML parsing of accounting tables

    These functions parse a given XML file and return an array of arrays as a
    result. On error they return an integer denoting the faulty line number, -1
    if file is not an XML file or null if given file cannot be opened.
*/

# parse file
# result structure: 
# $type = 'accounts': (id, parentid, acronym, name, type)
# $type = 'journal':  (id, debitacc, creditacc, value, receipt, description, time)
# $type = 'repeated': (id, debitacc, creditacc, value, receipt, description, nextdue, repDays, repMonths)
function get_xml( $filename, $type )
{
    global $get_xml_data;
    global $errline;

    $errline = null;

    $f = fopen( $filename, 'r' );
    if( !$f )
      return null;

    # read first chunk and see if it really is an XML file
    $buf = fread( $f, 4096 );
    if( !preg_match( '/^\s*<\?xml/i', $buf ) ) {
      fclose( $f );
      return -1;
    }
    
    #initialize XML parser
    $xp = xml_parser_create( "UTF-8" );
    xml_parser_set_option( $xp, XML_OPTION_TARGET_ENCODING, "UTF-8" );
    xml_set_element_handler( $xp, 'xml_'.$type.'_start_element_handler',
      'xml_'.$type.'_end_element_handler' );
    xml_set_character_data_handler( $xp, 'xml_character_data_handler' );

    $get_xml_data = array();

    # parse ahead
    do {
      if( !xml_parse( $xp, $buf, feof( $f ) ) ) {
          $l = xml_get_current_line_number( $xp );
          xml_parser_free( $xp );
          fclose( $f );
          return $l;
      }

      if( $errline ) {
          xml_parser_free( $xp );
          fclose( $f );
          return $errline;
      }
    } while( $buf = fread( $f, 4096 ) );

    # clean up and return data
    xml_parser_free( $xp );
    fclose( $f );
    return $get_xml_data;
}

########################################
# internal functions
########################################

function xml_character_data_handler( $parser, $data )
{
    global $xml_last_chardata;
    $xml_last_chardata .= $data;
}

function xml_accounts_start_element_handler( $parser, $elem, $at )
{
    static $acctypes = array(
      'balance' => 0,
      'asset' => 1,
      'liability' => 2,
      'revenue' => 3,
      'expense' => 4
    );

    if( $elem == 'ACCOUNTS' )
      return;

    global $errline, $xml_current_data;
    if( $errline ) return;

    if( $elem == 'ACCOUNT' && is_numeric( $at['ID'] ) && 
      is_numeric( $at['PARENT'] ) && !is_null( $acctypes[$at['TYPE']] ) )
      $xml_current_data = array( $at['ID'], $at['PARENT'], $at['ACRONYM'], 
          null, $acctypes[$at['TYPE']] );
    else
      $errline = xml_get_current_line_number( $parser );
}

function xml_accounts_end_element_handler( $parser, $elem, $attr )
{
    if( $elem == 'ACCOUNTS' )
      return;

    global $errline, $xml_current_data, $xml_last_chardata, $get_xml_data;

    if( $errline ) return;

    $xml_last_chardata = trim( $xml_last_chardata );

    if( $elem == 'ACCOUNT' && $xml_last_chardata && $xml_current_data ) {
      $xml_current_data[3] = $xml_last_chardata;
      array_push( $get_xml_data, $xml_current_data );
    } else
      $errline = xml_get_current_line_number( $parser );

    $xml_last_chardata = null;
    $xml_current_data = null;
}

function xml_journal_start_element_handler( $parser, $elem, $at )
{
    if( $elem == 'JOURNAL' )
      return;

    global $errline, $xml_current_data;
    if( $errline ) return;

    if( $elem == 'BOOKING' && is_numeric( $at['ID'] ) && 
      is_numeric( $at['DEBIT'] ) && is_numeric( $at['CREDIT'] ) &&
      is_numeric( $at['VALUE'] ) && $at['TIME'] )
      $xml_current_data = array( $at['ID'], $at['DEBIT'], $at['CREDIT'], 
          $at['VALUE'], $at['RECEIPT'], null, $at['TIME'] );
    else
      $errline = xml_get_current_line_number( $parser );
}

function xml_journal_end_element_handler( $parser, $elem, $attr )
{
    if( $elem == 'JOURNAL' )
      return;

    global $errline, $xml_current_data, $xml_last_chardata, $get_xml_data;

    if( $errline ) return;

    $xml_last_chardata = trim( $xml_last_chardata );

    if( $elem == 'BOOKING' && $xml_last_chardata && $xml_current_data ) {
      $xml_current_data[5] = $xml_last_chardata;
      array_push( $get_xml_data, $xml_current_data );
    } else
      $errline = xml_get_current_line_number( $parser );

    $xml_last_chardata = null;
    $xml_current_data = null;
}

function xml_repeated_start_element_handler( $parser, $elem, $at )
{
    if( $elem == 'REPEATED' )
      return;

    global $errline, $xml_current_data;
    if( $errline ) return;

    if( $elem == 'BOOKING' && is_numeric( $at['ID'] ) && 
      is_numeric( $at['DEBIT'] ) && is_numeric( $at['CREDIT'] ) &&
      is_numeric( $at['VALUE'] ) && $at['NEXTDUE'] && 
      is_numeric( $at['INTERVAL'] ) && 
      ( $at['REPEAT'] == 'daily' || $at['REPEAT'] == 'monthly' ) ) {
      if( $at['REPEAT'] == 'daily' )
          $repDays = $at['INTERVAL'];
      else
          $repMonths = $at['INTERVAL'];

      $xml_current_data = array( $at['ID'], $at['DEBIT'], $at['CREDIT'], 
          $at['VALUE'], $at['RECEIPT'], null, $at['NEXTDUE'], $repDays, $repMonths );
    } else
      $errline = xml_get_current_line_number( $parser );
}

function xml_repeated_end_element_handler( $parser, $elem, $attr )
{
    if( $elem == 'REPEATED' )
      return;

    global $errline, $xml_current_data, $xml_last_chardata, $get_xml_data;

    if( $errline ) return;

    $xml_last_chardata = trim( $xml_last_chardata );

    if( $elem == 'BOOKING' && $xml_last_chardata && $xml_current_data ) {
      $xml_current_data[5] = $xml_last_chardata;
      array_push( $get_xml_data, $xml_current_data );
    } else
      $errline = xml_get_current_line_number( $parser );

    $xml_last_chardata = null;
    $xml_current_data = null;
}

?>

Generated by  Doxygen 1.6.0   Back to index