Вход Регистрация
Файл: upload/include/library/phpfox/xml/parser.class.php
Строк: 197
<?php
/**
 * [PHPFOX_HEADER]
 */

defined('PHPFOX') or exit('NO DICE!');

/**
 * XML Parser
 * Class is used to convert an XML STRING into a ARRAY.
 * 
 * Sample XML code we are working with:
 * <code>
 * <foo var="value">
 *         <sample extra="info">
 *             This is some value.
 *         </sample>
 * </foo>
 * </code>
 * 
 * PHP code to parse XML STRING:
 * <code>
 * $aXmlData = Phpfox::getLib('xml.parser')->parse($sXml);
 * </code>
 * 
 * The variable $aXmlData will output the following array:
 * <code>
 * $aXmlData = array(
 *         'foo' => array(
 *             'var' => 'value',
 *             'sample' => array(
 *                 'extra' => 'info',
 *                 'value' => 'This is some value'
 *             )
 *         )
 * );
 * </code>
 * 
 * @copyright        [PHPFOX_COPYRIGHT]
 * @author            Raymond Benc
 * @package         Phpfox
 * @version         $Id: parser.class.php 2525 2011-04-13 18:03:20Z Raymond_Benc $
 */
class Phpfox_Xml_Parser
{
    
/**
     * XML object.
     *
     * @see xml_parser_create()
     * @var object
     */
    
private $_oXml null;
    
    
/**
     * XML string to parse.
     *
     * @var string
     */
    
private $_sXml;
    
    
/**
     * ARRAY of data we picked up and parsed from the XML string.
     *
     * @var array
     */
    
private $_aData = array();
    
    
/**
     * Error ID#.
     *
     * @var int
     */
    
private $_iError 0;    
    
    
/**
     * Stack XML.
     *
     * @var array
     */
    
private $_aStack = array();
    
    
/**
     * CDATA string.
     *
     * @var string
     */
    
private $_sCdata;
    
    
/**
     * Check to include the first tag.
     *
     * @var bool
     */
    
private $_bIncludeFirstTag false;
    
    
/**
     * Total number of tags.
     *
     * @var int
     */
    
private $_iTagCnt 0;
    
    
/**
     * Error code.
     *
     * @var int
     */
    
private $_iErrorCode 0;
    
    
/**
     * Error line.
     *
     * @var int
     */
    
private $_iErrorLine 0;

    
/**
    * Class constructor.
    *
    */
    
public function __construct()
    {
    }
    
    
/**
     * Get the XML content.
     *
     * @param string $mFile XML data or XML file.
     * @return string XML data.
     */
    
public function getXml($mFile)
    {        
        if (!
preg_match("/<(.*?)>/i"$mFile) && file_exists($mFile))        
        {
            return 
file_get_contents($mFile);
        }
        
        return 
$mFile;
    }

    
/**
     * Parse XML code and convert into an ARRAY.
     *
     * @param string $mFile XML data or XML file name.
     * @param string $sEncoding Encoding.
     * @param bool $bEmptyData TRUE to empty XML data.
     * @return mixed FALSE if errors were found, ARRAY if no errors and XML was converted into an ARRAY.
     */
    
public function parse($mFile$sEncoding 'ISO-8859-1'$bEmptyData true)
    {
        
$this->_sXml $this->getXml($mFile);
        
        if (empty(
$this->_sXml) || $this->_iError 0)
        {            
            return 
false;
        }

        if (!(
$this->_oXml xml_parser_create($sEncoding)))
        {            
            return 
false;
        }
        
        
xml_parser_set_option($this->_oXmlXML_OPTION_SKIP_WHITE0);
        
xml_parser_set_option($this->_oXmlXML_OPTION_CASE_FOLDING0);
        
xml_set_character_data_handler($this->_oXml, array(&$this'_handleCdata'));
        
xml_set_element_handler($this->_oXml, array(&$this'_handleElementStart'), array(&$this'_handleElementEnd'));        
    
        
xml_parse($this->_oXml$this->_sXml);
        
        
$bError xml_get_error_code($this->_oXml);

        if (
$bEmptyData)
        {
            
$this->_sXml '';
            
$this->_aStack = array();
            
$this->_sCdata '';
        }

        if (
$bError)
        {            
            
$this->_iErrorCode = @xml_get_error_code($this->_oXml);
            
$this->_iErrorLine = @xml_get_current_line_number($this->_oXml);
            
            
xml_parser_free($this->_oXml);

            return 
Phpfox_Error::trigger($this->errorString(), E_USER_ERROR);
        }

        
xml_parser_free($this->_oXml);

        return 
$this->_aData;
    }
    
    
/**
     * Error phrase.
     *
     * @return string
     */
    
public function errorString()
    {        
        if (
$sError xml_error_string($this->_iErrorCode))
        {            
            return 
$sError;
        }
        else
        {            
            return 
'unknown';
        }
    }
    
    
/**
     * Error line.
     *
     * @return int
     */
    
public function errorLine()
    {
        if (
$this->_iErrorLine)
        {
            return 
$this->_iErrorLine;
        }
        else
        {
            return 
0;
        }
    }

    
/**
     * Error code.
     *
     * @return int
     */
    
public function errorCode()
    {
        if (
$this->_iErrorCode)
        {
            return 
$this->_iErrorCode;
        }
        else
        {
            return 
0;
        }
    }    

    
/**
     * Handle CDATA by storing it in a variable.
     *
     * @param object $oParser Object parser.
     * @param string $sData CDATA string we parsed.
     */
    
private function _handleCdata(&$oParser$sData)
    {
        
$this->_sCdata .= $sData;
    }

    
/**
     * Handle the start of an element.
     *
     * @param object $oParser Object parser.
     * @param string $sName Name of the element.
     * @param array $aAttributes List of attributes.
     */
    
private function _handleElementStart(&$oParser$sName$aAttributes)
    {
        
$this->_sCdata '';

        foreach (
$aAttributes AS $sKey => $sValue)
        {
            if (
preg_match('#&[a-z]+;#i'$sValue))
            {
                
$aAttributes[$sKey] = Phpfox::getLib('parse.format')->unhtmlspecialchars($sValue);
            }
        }

        
array_unshift($this->_aStack, array(
            
'name' => $sName
            
'attributes' => $aAttributes
            
'tag_count' => ++$this->_iTagCnt
        
));
    }

    
/**
     * Handle the end of an element.
     *
     * @param unknown_type $oParser Object parser.
     * @param unknown_type $sName Name of the element.
     */
    
private function _handleElementEnd(&$oParser$sName)
    {
        
$aTag array_shift($this->_aStack);
        
        if (
$aTag['name'] != $sName)
        {
            return;
        }

        
$sOutput $aTag['attributes'];

        if (
trim($this->_sCdata) !== '' || $aTag['tag_count'] == $this->_iTagCnt)
        {
            if (
sizeof($sOutput) == 0)
            {
                
$sOutput $this->_unescapeCdata($this->_sCdata);
            }
            else
            {
                
$this->_addNode($sOutput'value'$this->_unescapeCdata($this->_sCdata));
            }
        }

        if (isset(
$this->_aStack[0]))
        {
            
$this->_addNode($this->_aStack[0]['attributes'], $sName$sOutput);
        }
        else
        {
            if (
$this->_bIncludeFirstTag)
            {
                
$this->_aData = array($sName => $sOutput);
            }
            else
            {
                
$this->_aData $sOutput;
            }
        }


        
$this->_sCdata '';
    }

    
/**
     * Add children.
     *
     * @param array $aChildrens Child ARRAY.
     * @param string $sName Name of the tag.
     * @param string $sValue Value of the tag.
     */
    
private function _addNode(&$aChildrens$sName$sValue)
    {
        if (!
is_array($aChildrens) || !in_array($sNamearray_keys($aChildrens)))
        {
            
$aChildrens[$sName] = $sValue;
        }
        elseif (
is_array($aChildrens[$sName]) && isset($aChildrens[$sName][0]))
        {
            
$aChildrens[$sName][] = $sValue;
        }
        else
        {
            
$aChildrens[$sName] = array($aChildrens[$sName]);
            
$aChildrens[$sName][] = $sValue;
        }
    }

    
/**
     * Unescape CDATA.
     *
     * @param string $sXml XML code to parse.
     * @return string Converted XML unescaped CDATA.
     */
    
private function _unescapeCdata($sXml)
    {
        static 
$sFind$sReplace;

        if (!
is_array($sFind))
        {
            
$sFind = array('�![CDATA['']]�'"rn""n");
            
$sReplace = array('<![CDATA['']]>'"n""rn");
        }

        return 
str_replace($sFind$sReplace$sXml);
    }
}

?>
Онлайн: 1
Реклама