⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 rss_parse_magpie.inc.php

📁 在综合英文版XOOPS 2.09, 2.091, 2.092 的基础上正式发布XOOPS 2.09中文版 XOOPS 2.09x 版主要是PHP5升级、bug修正和安全补正: 1 全面兼容PHP 5.
💻 PHP
📖 第 1 页 / 共 2 页
字号:
<?php

/**
* Project:     MagpieRSS: a simple RSS integration tool
* File:        rss_parse.inc  - parse an RSS or Atom feed
*               return as a simple object.
*
* Handles RSS 0.9x, RSS 2.0, RSS 1.0, and Atom 0.3
*
* The lastest version of MagpieRSS can be obtained from:
* http://magpierss.sourceforge.net
*
* For questions, help, comments, discussion, etc., please join the
* Magpie mailing list:
* magpierss-general@lists.sourceforge.net
*
* @author           Kellan Elliott-McCrea <kellan@protest.net>
* @version          0.7a
* @license          GPL
*
*/

define('MAGPIE_DEBUG', 0);

define('RSS', 'RSS');
define('ATOM', 'Atom');


/**
* Hybrid parser, and object, takes RSS as a string and returns a simple object.
*
* see: rss_fetch.inc for a simpler interface with integrated caching support
*
*/
class MagpieRSS {
    var $parser;

    var $current_item   = array();  // item currently being parsed
    var $items          = array();  // collection of parsed items
    var $channel        = array();  // hash of channel fields
    var $textinput      = array();
    var $image          = array();
    var $feed_type;
    var $feed_version;
    var $encoding       = '';       // output encoding of parsed rss

    var $_source_encoding = '';     // only set if we have to parse xml prolog

    var $ERROR = "";
    var $WARNING = "";

    // define some constants

    var $_CONTENT_CONSTRUCTS = array('content', 'summary', 'info', 'title', 'tagline', 'copyright');
    var $_KNOWN_ENCODINGS    = array('UTF-8', 'US-ASCII', 'ISO-8859-1');

    // parser variables, useless if you're not a parser, treat as private
    var $stack              = array(); // parser stack
    var $inchannel          = false;
    var $initem             = false;
    var $incontent          = false; // if in Atom <content mode="xml"> field
    var $intextinput        = false;
    var $inimage            = false;
    var $current_field      = '';
    var $current_namespace  = false;


    /**
     *  Set up XML parser, parse source, and return populated RSS object..
     *
     *  @param string $source           string containing the RSS to be parsed
     *
     *  NOTE:  Probably a good idea to leave the encoding options alone unless
     *         you know what you're doing as PHP's character set support is
     *         a little weird.
     *
     *  NOTE:  A lot of this is unnecessary but harmless with PHP5
     *
     *
     *  @param string $output_encoding  output the parsed RSS in this character
     *                                  set defaults to ISO-8859-1 as this is PHP's
     *                                  default.
     *
     *                                  NOTE: might be changed to UTF-8 in future
     *                                  versions.
     *
     *  @param string $input_encoding   the character set of the incoming RSS source.
     *                                  Leave blank and Magpie will try to figure it
     *                                  out.
     *
     *
     *  @param bool   $detect_encoding  if false Magpie won't attempt to detect
     *                                  source encoding. (caveat emptor)
     *
     */
    function MagpieRSS ($source, $output_encoding='ISO-8859-1',
                        $input_encoding=null, $detect_encoding=true)
    {
        # if PHP xml isn't compiled in, die
        #
        if (!function_exists('xml_parser_create')) {
            $this->error( "Failed to load PHP's XML Extension. " .
                          "http://www.php.net/manual/en/ref.xml.php",
                           E_USER_ERROR );
        }

        list($parser, $source) = $this->create_parser($source,
                $output_encoding, $input_encoding, $detect_encoding);


        if (!is_resource($parser)) {
            $this->error( "Failed to create an instance of PHP's XML parser. " .
                          "http://www.php.net/manual/en/ref.xml.php",
                          E_USER_ERROR );
        }


        $this->parser = $parser;

        # pass in parser, and a reference to this object
        # setup handlers
        #
        xml_set_object( $this->parser, $this );
        xml_set_element_handler($this->parser,
                'feed_start_element', 'feed_end_element' );

        xml_set_character_data_handler( $this->parser, 'feed_cdata' );

        $status = @xml_parse( $this->parser, $source );

        if (! $status ) {
            $errorcode = xml_get_error_code( $this->parser );
            if ( $errorcode != XML_ERROR_NONE ) {
                $xml_error = xml_error_string( $errorcode );
                $error_line = xml_get_current_line_number($this->parser);
                $error_col = xml_get_current_column_number($this->parser);
                $errormsg = "$xml_error at line $error_line, column $error_col";

                $this->error( $errormsg );
            }
        }

        xml_parser_free( $this->parser );

        $this->normalize();
    }

    function feed_start_element($p, $element, &$attrs) {
        $el = $element = strtolower($element);
        $attrs = array_change_key_case($attrs, CASE_LOWER);

        // check for a namespace, and split if found
        $ns = false;
        if ( strpos( $element, ':' ) ) {
            list($ns, $el) = split( ':', $element, 2);
        }
        if ( $ns and $ns != 'rdf' ) {
            $this->current_namespace = $ns;
        }

        # if feed type isn't set, then this is first element of feed
        # identify feed from root element
        #
        if (!isset($this->feed_type) ) {
            if ( $el == 'rdf' ) {
                $this->feed_type = RSS;
                $this->feed_version = '1.0';
            }
            elseif ( $el == 'rss' ) {
                $this->feed_type = RSS;
                $this->feed_version = $attrs['version'];
            }
            elseif ( $el == 'feed' ) {
                $this->feed_type = ATOM;
                $this->feed_version = $attrs['version'];
                $this->inchannel = true;
            }
            return;
        }

        if ( $el == 'channel' )
        {
            $this->inchannel = true;
        }
        elseif ($el == 'item' or $el == 'entry' )
        {
            $this->initem = true;
            if ( isset($attrs['rdf:about']) ) {
                $this->current_item['about'] = $attrs['rdf:about'];
            }
        }

        // if we're in the default namespace of an RSS feed,
        //  record textinput or image fields
        elseif (
            $this->feed_type == RSS and
            $this->current_namespace == '' and
            $el == 'textinput' )
        {
            $this->intextinput = true;
        }

        elseif (
            $this->feed_type == RSS and
            $this->current_namespace == '' and
            $el == 'image' )
        {
            $this->inimage = true;
        }

        # handle atom content constructs
        elseif ( $this->feed_type == ATOM and in_array($el, $this->_CONTENT_CONSTRUCTS) )
        {
            // avoid clashing w/ RSS mod_content
            if ($el == 'content' ) {
                $el = 'atom_content';
            }

            $this->incontent = $el;


        }

        // if inside an Atom content construct (e.g. content or summary) field treat tags as text
        elseif ($this->feed_type == ATOM and $this->incontent )
        {
            // if tags are inlined, then flatten
            $attrs_str = join(' ',
                    array_map('map_attrs',
                    array_keys($attrs),
                    array_values($attrs) ) );

            $this->append_content( "<$element $attrs_str>"  );

            array_unshift( $this->stack, $el );
        }

        // Atom support many links per containging element.
        // Magpie treats link elements of type rel='alternate'
        // as being equivalent to RSS's simple link element.
        //
        elseif ($this->feed_type == ATOM and $el == 'link' )
        {
            if ( isset($attrs['rel']) and $attrs['rel'] == 'alternate' )
            {
                $link_el = 'link';
            }
            else {
                $link_el = 'link_' . $attrs['rel'];
            }

            $this->append($link_el, $attrs['href']);
        }
        // set stack[0] to current element
        else {
            array_unshift($this->stack, $el);
        }
    }



    function feed_cdata ($p, $text) {

        if ($this->feed_type == ATOM and $this->incontent)
        {
            $this->append_content( $text );
        }
        else {
            $current_el = join('_', array_reverse($this->stack));
            $this->append($current_el, $text);
        }
    }

    function feed_end_element ($p, $el) {
        $el = strtolower($el);

        if ( $el == 'item' or $el == 'entry' )
        {
            $this->items[] = $this->current_item;
            $this->current_item = array();
            $this->initem = false;
        }
        elseif ($this->feed_type == RSS and $this->current_namespace == '' and $el == 'textinput' )
        {
            $this->intextinput = false;
        }
        elseif ($this->feed_type == RSS and $this->current_namespace == '' and $el == 'image' )
        {
            $this->inimage = false;
        }
        elseif ($this->feed_type == ATOM and in_array($el, $this->_CONTENT_CONSTRUCTS) )
        {
            $this->incontent = false;
        }
        elseif ($el == 'channel' or $el == 'feed' )
        {
            $this->inchannel = false;
        }
        elseif ($this->feed_type == ATOM and $this->incontent  ) {
            // balance tags properly
            // note:  i don't think this is actually neccessary
            if ( $this->stack[0] == $el )
            {
                $this->append_content("</$el>");
            }
            else {
                $this->append_content("<$el />");
            }

            array_shift( $this->stack );
        }
        else {
            array_shift( $this->stack );
        }

        $this->current_namespace = false;
    }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -