Html Parser Class

This is a HTML parser class, used to parse HTML and XML. One of the unique features of this class is that it supports the innerHTML property.
<?php

/**
 * HTML/XML Parser Class
 *
 * This is a helper class that is used to parse HTML and XML. A unique feature of this parsing class 
 * is the fact that it includes support for innerHTML (which isn't easy to do).
 *
 * @author Dennis Pallett
 * @copyright Dennis Pallett 2006
 * @package HTML_Parser
 * @version 1.0
 */

// Helper Class
// To parse HTML/XML
Class HTML_Parser {
    // Private properties
    var $_parser;
    var $_tags = array();
    var $_html;
    var $output = array();
    var $strXmlData;
    var $_level = 0;
    var $_outline;
    var $_tagcount = array();
    var $xml_error = false;
    var $xml_error_code;
    var $xml_error_string;
    var $xml_error_line_number;

    function get_html () {
        return $this->_html;
    }

    function parse($strInputXML) {
        $this->output = array();

        // Translate entities
        $strInputXML = $this->translate_entities($strInputXML);

        $this->_parser = xml_parser_create ();
        xml_parser_set_option($this->_parser, XML_OPTION_CASE_FOLDING, true);
        xml_set_object($this->_parser,$this);
        xml_set_element_handler($this->_parser, "tagOpen", "tagClosed");
          
        xml_set_character_data_handler($this->_parser, "tagData");
      
        $this->strXmlData = xml_parse($this->_parser,$strInputXML );

        if (!$this->strXmlData) {
            $this->xml_error = true;
            $this->xml_error_code = xml_get_error_code($this->_parser);
            $this->xml_error_string = xml_error_string(xml_get_error_code($this->_parser));
            $this->xml_error_line_number =  xml_get_current_line_number($this->_parser);
            return false;
        }

        return $this->output;
    }

    function tagOpen($parser, $name, $attr) {
        // Increase level
        $this->_level++;

        // Create tag:
        $newtag = $this->create_tag($name, $attr);

        // Build tag
        $tag = array("name"=>$name,"attr"=>$attr, "level"=>$this->_level);

        // Add tag
        array_push ($this->output, $tag);

        // Add tag to this level
        $this->_tags[$this->_level] = $tag;

        // Add to HTML
        $this->_html .= $newtag;

        // Add to outline
        $this->_outline .= $this->_level . $newtag;
    }

    function create_tag ($name, $attr) {
        // Create tag:
        # Begin with name
        $tag = '<' . strtolower($name) . ' ';

        # Create attribute list
        foreach ($attr as $key=>$val) {
            $tag .= strtolower($key) . '="' . htmlentities($val) . '" ';
        }

        # Finish tag
        $tag = trim($tag);
        
        switch(strtolower($name)) {
            case 'br':
            case 'input':
                $tag .= ' /';
            break;
        }

        $tag .= '>';

        return $tag;
    }

    function tagData($parser, $tagData) {
        if(trim($tagData)) {
            if(isset($this->output[count($this->output)-1]['tagData'])) {
                $this->output[count($this->output)-1]['tagData'] .= $tagData;
            } else {
                $this->output[count($this->output)-1]['tagData'] = $tagData;
            }
        }

        $this->_html .= htmlentities($tagData);
        $this->_outline .= htmlentities($tagData);
    }
  
    function tagClosed($parser, $name) {
        // Add to HTML and outline
        switch (strtolower($name)) {
            case 'br':
            case 'input':
                break;
            default:
            $this->_outline .= $this->_level . '</' . strtolower($name) . '>';
            $this->_html .= '</' . strtolower($name) . '>';
        }

        // Get tag that belongs to this end
        $tag = $this->_tags[$this->_level];
        $tag = $this->create_tag($tag['name'], $tag['attr']);

        // Try to get innerHTML
        $regex = '%' . preg_quote($this->_level . $tag, '%') . '(.*?)' . preg_quote($this->_level . '</' . strtolower($name) . '>', '%') . '%is';
        preg_match ($regex, $this->_outline, $matches);

        // Get innerHTML
        if (isset($matches['1'])) {
            $innerhtml = $matches['1'];
        }
        
        // Remove level identifiers
        $this->_outline = str_replace($this->_level . $tag, $tag, $this->_outline);
        $this->_outline = str_replace($this->_level . '</' . strtolower($name) . '>', '</' . strtolower($name) . '>', $this->_outline);

        // Add innerHTML
        if (isset($innerhtml)) {
            $this->output[count($this->output)-1]['innerhtml'] = $innerhtml;
        }

        // Fix tree
        $this->output[count($this->output)-2]['children'][] = $this->output[count($this->output)-1];
        array_pop($this->output);

        // Decrease level
        $this->_level--;
    }

    function translate_entities($xmlSource, $reverse =FALSE) {
        static $literal2NumericEntity;
        
        if (empty($literal2NumericEntity)) {
            $transTbl = get_html_translation_table(HTML_ENTITIES);

            foreach ($transTbl as $char => $entity) {
                if (strpos('&"<>', $char) !== FALSE) continue;
                    $literal2NumericEntity[$entity] = ''.ord($char).';';
                }
            }

            if ($reverse) {
                return strtr($xmlSource, array_flip($literal2NumericEntity));
            } else {
                return strtr($xmlSource, $literal2NumericEntity);
            }
      }
}

// To be used like this
$parser = new HTML_Parser;
$output = $parser->parse($html);

print_r ($output);

?>

时间: 2024-10-04 01:23:45

Html Parser Class的相关文章

解析Html页面:HTML Parser的试用

页面 最近在研究lucene的全文检索,在很多地方需要解析或者说分析Html内容或者Html页面,Lucene本身的演示程序中也提供了一个Html Parser,但是不是纯Java的解决方案.于是到处搜索,在网上找到了一个"HTMLParser". 网址是: http://htmlparser.sourceforge.net ,当前版本为1.5. 下载下来,试用一番,感觉不错,完全能满足lucene解析Html的需求. 过几天贴出lucene进行全文检索的代码.(检索本站的文章等).

在Android应用中使用HTML Parser便捷的解析html内容

概述 随着移动互联网的发展,更多的内容需要从传统互联网延伸到移动终端呈现.一般的做法有三 种:1. Web APP:利用 HTML5 技术,例如 JQuery mobile.DojoX mobile,在服务器端对网页进行移动优化 .2. Hybrid APP:利用 HTML5 技术,以及 phonegap 等框架生成 APP,可以通过 phonegap 直接调用手机操 作系统的 API,比如传感器,响铃等.3. 原生态 APP:将要显示的内容下载到本地,解析后重新布局并显示 . 三种移动应用的优

PostgreSQL Oracle兼容性 之 - parser SQL保留|关键字(keywrods)大全

标签 PostgreSQL , keywords , 关键字 , Oracle 兼容性 背景 PostgreSQL数据库中有哪些关键字,这些关键字的使用限制如何? https://www.postgresql.org/docs/10/static/sql-keywords-appendix.html 文档中的说明并不是特别清晰,(并且KEYWORDS与版本强相关),所以使用pg_get_keywords这个系统函数得到的,更加准确可读. https://www.postgresql.org/do

JDK的Parser来解析Java源代码详解_java

在JDK中,自带了一套相关的编译API,可以在Java中发起编译流程,解析Java源文件然后获取其语法树,在JDK的tools.jar(OSX下可以在/Library/Java/JavaVirtualMachines/jdk_version/Contents/Home/lib中找到)中包含着这整套API,但是这却不是Oracle和OpenJDK发布中的公开API,因此对于这套API,并没有官方的正式文档来进行说明.但是,也有不少项目利用了这套API来做了不少事情,例如大名鼎鼎的lombok使用了

simple-有大神用过PHP Simple HTML DOM Parser这个吗 求指教

问题描述 有大神用过PHP Simple HTML DOM Parser这个吗 求指教 如何用这个获取 <th align="center" width="10%" class="sortable"> 课程号 </th> 获取到 课程号 这三个字 解决方案 include 'simple_html_dom.php'; $s = '<th align="center" width="10%

选择使用正确的 Markdown Parser

本文讲的是选择使用正确的 Markdown Parser, 以下客座文章由Ray Villalobos提供.在这篇文章中Ray将要去探索很多种不同的Markdown语法.所有的这些MarkDown变种均提供了不同的特性,都超越传统的Markdown语法,却又相互之间又各有不同.如果你正在挑选一门Markdown语言使用(或是提供给你的Web产品的用户使用),那你就值得的去了解它们,一旦选定就很难再切换到别的Markdown版本而且挑选的结果依赖于你需要哪些特性.Ray提供的一门关于MarkDow

java-句法分析工具Stanford Parser 如何提取句法树结构中的特定节点

问题描述 句法分析工具Stanford Parser 如何提取句法树结构中的特定节点 20C 如题,现在需要使用Stanford Parser句法分析工具所以求问.给定一个语句,在使用其生成短语结构树后,要取出在同一短语内的词(这些词,或者说叶节点它们的上一层或者上某层会有交集)这是如何办到的?

ios-iOS json parser 解析字符串

问题描述 iOS json parser 解析字符串 ( { address = ""xx-xx-xxxxx - street x - country""; email = ""ravi@gmail.com""; gender = male; id = c200; name = ""Ravi Tamada""; phone = { home = ""00 000000

Greenplum,HAWQ interval parser带来的问题 - TPCH 测试注意啦

Greenplum,HAWQ interval parser带来的问题 - TPCH 测试注意啦 作者 digoal 日期 2016-10-11 标签 Greenplum , PostgreSQL , interval , parser 背景 interval是用来表达时间间隔的数据类型,比如1年,或者1分钟,或者1天零多少小时分钟等. postgres=# select interval '100 year 2 month 1 day 1:00:01.11'; interval -------