• 处理 HTML 的 HtmlDocument 类实现


    一个 XML 处理很复杂, 但在 .net 却非常方便, 因为系统已提供了 Xml 处理的工具。

    一个 Xml 的文件处理是这个格式:

    XmlDocument xml = new XmlDocument();
    
    xml.Load("aa.xml");
    
    xml.AppendChild(xml.CreateElement("r"));
    
    
    

    但是 HTML 就不如此方便了, 当然 .net 有 HtmlDocument 类 (不知道 ? )

    System.Windows.Form.UI.HtmlDocument   这是控件, 内部是 mshtml.dll 完成, 在 web 就无法使用了。

    所以非常要做一个 像 XML 一样处理 HTML 的类。

    操作 HTML 可以

    HtmlDocument html = new HtmlDocument();
    
    html.Load(new Uri(http://www.baidu.com));
    
    html.GetElementById("name").Value = "3";
     

    那就非常好了。

    XML 和 HTML 可以解释为继承  HTML 来自 XML

    XmlDocument 类的许多成员在 HtmlDocument 也存在

    且 HtmlDocument 还有 GetElementById GetElementsByName 的函数

    HtmlDocument 的成员不可自定义, 而是有标准的规范的。  

    首先 要知道:

    HTMLNode 其实是1个单链表。

    各元素之间 上一个节点指下个节点。 最后一个节点指父节点。

    我之所以强调是因为很多人和我一样一直把它作为非链表的。

    所以 HtmlNode集合其实是空的,只是提供游走链表的东西。

    第二:

    和 XML 相比,  HTML 处理节点时不同的地方,也是写这个类最困难的地方:

    HTML 可以不规范。

    如下:

    <html><head></html>

    这对 XML 来说,是个抛出异常的好地方

    XML说: 你给的东西不像话,我不干了, 杂的?

    HTML说: 我很友善,我耐心的告诉你啥错了,我帮你修复。

    于是 HTML 处理相当复杂。

    如果碰到一个 </html> 其父节点不是 <html> 则应加入 </head>  。

    类似一个栈, 有进必要出, 没出就抓出来

    第三:

    <p> 是讨厌的东西,因为 <p></p> 或 <p> 都合法。 需要获得下个节点才能决定<p>

    一些<br> 之类的也有额外处理

    接下来,可以开做了:

    先写 HtmlNode 类

    public abstract class HtmlNode {
    
         public string NodeName { get; set; }
    
        public NodeType NodeType  { get; set; }
    
        public HtmlNode NextSilding   { get; set; }
    
    }
    
    
    

    然后是 HtmlAttributionCollection, HtmlAttribution

    然后是 HtmlElement 类

    public class  HtmlElement : HtmlNode {
    
      HtmlAttributionCollection Attributions;
    
         public string TagName   {get; set;}
    
    }
    
    
    

    最后是 HtmlDocument

    这些类做好后,继续 词法分析工具

    名字为   

    HtmlParser

    这个类负责读取html  , 并获取当前位置,如 <html><head id="d">s</html>

    将处理为

    <html>
    
    <head id="d">
    
    s
    
     </html>
    
    
    

    这样就可知道基本的内容。

    最后 HtmlLoader   为节点语法分析

    HtmlLoader 有个跟节点(默认 HtmlDocument)

    每次载入节点都存至跟节点。  ( 适合 InnerHTML = "" 调用)

    HtmlLoader 管理一个栈,负责调整树。

    如发现<html> 压入。

    发现 </html> 把栈内所有<html>之外的都移除, 再移除  <html>

    最后加点常用元素

    如 HtmlImageElement , 这样就是完整的 HTML 工具

    在系统的 XML 中 使用了 NameTable 实现字符串缓存。

    这个缓存由2个优点:

      避免同一个 字串占多个位置

      比较字串只要比较字符的引用,达到高速的比较。

    因此 HTML 同样可以这样操作


     最后, 作为 HTML 处理, 当然得提供类似浏览器的一些操作,如表单的提交。

    因此 特地准备了 Form 节点, 提供提交函数,将文档值处理后上交。

    这可以实现自动填 form ,自动登录等。

    当然速度肯定比用控件好多,不过无法处理js部分。

  • 相关阅读:
    序列化流与反序列化流
    io流之Properties类
    io流之转换流与缓冲流
    Io流之File概述(递归/字节流/字符流)
    基本数据类型包装/System类/Math类/Arrays类
    Date类概述与Calendar类概念
    String类型概述
    20180926 小小插件 (弹窗)
    20180901 文件加载 错误处理 错误的触发
    20180828 优化留言板 功能(增加 删除 修改 查看)!
  • 原文地址:https://www.cnblogs.com/xuld/p/1924334.html
Copyright © 2020-2023  润新知