运用.NET Framework类来解析HTML文件、读取数据并不是最容易的。虽然你可以用.NET Framework中的许多类(如StreamReader)来逐行解析文件,但XmlReader提供的API并不是“取出即可用(out of the box)”的,因为HTML的格式不规范。你可以用正则表达式(regular expression),但如果你对这些表达式运用不熟练,你可能开始时会觉得它们有些难。

Microsoft的XML大师Chris Lovett最近在http://www.gotdotnet.com网站上发布了一个新的SGML解析器,叫做SgmlReader,它可以解析HTML文件,甚至将它们转换成一个格式规范的结构。SgmlReader派生于XmlReader,这就是说,你可以像运用诸如XmlTextReader这样的类来解析XML文件那样来解析HTML文件。在本文中,我将介绍如何用SgmlReader类来解析HTML文件并生成格式规范的HTML,从而使你可以用XPath语句来读取数据。

创建一个SgmlReader实例来解析HTML
在开始运用SgmlReader前,从gotdotnet.com下载它,并将assembly放到你的应用程序bin folder中。在可以运用assembly集后,编写代码来读取你想解析的HTML。在本文的例子中,我们用了HttpWebRequest和HttpWebResponse对象来访问一个远程的HTML文件: HttpWebRequest req = (HttpWebRequest)WebRequest.Create(uri);HttpWebResponse res = (HttpWebResponse)req.GetResponse();StreamReader sReader = new StreamReader(res.GetResponseStream());

在得到远程的HTML文件后,你就可以创建一个SgmlReader类的实例了。通过将其DocType属性设置为“HTML”,让用户知道你正在处理HTML文件: SgmlReader reader = new SgmlReader();reader.DocType = "HTML";

HTML文件的响应流可以被加载到SgmlReader实例,通过其InputStream属性进行解析。首先将HTML文件流加载到一个TextReader对象,然后将TextReader赋值给InputStream属性: reader.InputStream = new StringReader(sReader.ReadToEnd());

现在,你就可以通过调用SgmlReader的Read()方法来解析HTML文件了: sw = new StringWriter();writer = new XmlTextWriter(sw);writer.Formatting = Formatting.Indented;while (reader.Read()) { if (reader.NodeType != XmlNodeType.Whitespace) writer.WriteNode(reader, true); }}

因为SgmlReader创建了格式规范的HTML,所以你可以用XPath语句来读取不同的节点。下面的代码说明了如何将SgmlReader生成的输出结果加载到一个XPathNavigator,然后如何用一个XPath语句来查询HTML文件结构: StringBuilder sb = new StringBuilder();XPathDocument doc = new XPathDocument(new StringReader(sw.ToString()));XPathNavigator nav = doc.CreateNavigator();XPathNodeIterator nodes = nav.Select(xpath);while (nodes.MoveNext()) { sb.Append(nodes.Current.Value);}return sb.ToString();

点击此处来查看SgmlReader类的一个实例演示

如果你对XPath语言已经很熟悉,并了解.NET Framework中不同的XML解析API了,那么你就可以很容易地用SgmlReader类来解析HTML并读取数据了。

部分代码C#

private string GetWellFormedHTML(string uri,string xpath) ...{
            StreamReader sReader = null;
            StringWriter sw = null;
            SgmlReader reader = null;
            XmlTextWriter writer = null;
            try ...{
                if (uri == String.Empty) uri = "http://www.XMLforASP.NET";
                HttpWebRequest req = (HttpWebRequest)WebRequest.Create(uri);
                HttpWebResponse res = (HttpWebResponse)req.GetResponse();
                sReader = new StreamReader(res.GetResponseStream());
                reader = new SgmlReader();
                reader.DocType = "HTML";
                reader.InputStream = new StringReader(sReader.ReadToEnd());
                sw = new StringWriter();
                writer = new XmlTextWriter(sw);
                writer.Formatting = Formatting.Indented;
                //writer.WriteStartElement("Test");
                while (reader.Read()) ...{
                    if (reader.NodeType != XmlNodeType.Whitespace) ...{
                        writer.WriteNode(reader, true);
                    }
                } 
                //writer.WriteEndElement();
                if (xpath == null) ...{
                    return sw.ToString();   
                } else ...{ //Filter out nodes from HTML
                    StringBuilder sb = new StringBuilder();
                    XPathDocument doc = new XPathDocument(new StringReader(sw.ToString()));
                    XPathNavigator nav = doc.CreateNavigator();
                    XPathNodeIterator nodes = nav.Select(xpath);
                    while (nodes.MoveNext()) ...{
                        sb.Append(nodes.Current.Value + " ");
                    }
                    return sb.ToString();
                }
            } catch (Exception exp) ...{
                writer.Close(); 
                reader.Close();
                sw.Close();
                sReader.Close();
                return exp.Message;
            }
        }

解析HTML文件 - 运用SgmlReader类来解析HTML文件的更多相关文章

  1. ZIP解压缩文件的工具类【支持多级文件夹|全】

    ZIP解压缩文件的工具类[支持多级文件夹|全] 作者:Vashon 网上有非常多的加压缩演示样例代码.可是都仅仅是支持一级文件夹的操作.假设存在多级文件夹的话就不行了. 本解压缩工具类经过多次检查及重 ...

  2. 使用CodeSmith快速生成映射文件和映射类

    一 CodeSmith简介 本文以表自动生成NHibernate的映射文件和映射类的实例来说明一下本软件的使用方法. CodeSmith是一种基于模板的代码生成工具,其使用类似于ASP.NET的语法来 ...

  3. 在头文件中声明class 类 与 include类所在的头文件区别---理解

    在头文件中声明class 类 与 include类所在的头文件的理解: 在头文件中,声明类 它告诉编译器:存在这样的类.而实际的类则可以位于同一个编译单元中,也可以放在其他编译单元中.没有这个类原型, ...

  4. hibernate 的映射文件快速生成:使用CodeSmith快速生成映射文件和映射类

    一 CodeSmith简介 本文以表自动生成NHibernate的映射文件和映射类的实例来说明一下本软件的使用方法. CodeSmith是一种基于模板的代码生成工具,其使用类似于ASP.NET的语法来 ...

  5. DuiLib 源码分析之解析xml类CMarkup & CMarkupNode 头文件

    xml使用的还是比较多的,duilib界面也是通过xml配置实现的 duilib提供了CMarkkup和CMarkupNode类解析xml,使用起来也是比较方便的,比较好奇它是怎么实现的,如果自己来写 ...

  6. java工具类mht转html格式文件 及简单的HTML解析

    package com.szy.project.utils; import java.io.BufferedInputStream; import java.io.BufferedOutputStre ...

  7. 无废话Android之android下junit测试框架配置、保存文件到手机内存、android下文件访问的权限、保存文件到SD卡、获取SD卡大小、使用SharedPreferences进行数据存储、使用Pull解析器操作XML文件、android下操作sqlite数据库和事务(2)

    1.android下junit测试框架配置 单元测试需要在手机中进行安装测试 (1).在清单文件中manifest节点下配置如下节点 <instrumentation android:name= ...

  8. Tomcat源码分析——SERVER.XML文件的加载与解析

    前言 作为Java程序员,对于Tomcat的server.xml想必都不陌生.本文基于Tomcat7.0的Java源码,对server.xml文件是如何加载和解析的进行分析. 加载 server.xm ...

  9. Fixflow引擎解析(三)(模型) - 创建EMF模型来读写XML文件

    Fixflow引擎解析(四)(模型) - 通过EMF扩展BPMN2.0元素 Fixflow引擎解析(三)(模型) - 创建EMF模型来读写XML文件 Fixflow引擎解析(二)(模型) - BPMN ...

随机推荐

  1. OpenCV_1.0安装包下载

    OpenCV_1.0安装包下载 点击下载

  2. Eureka 使用Spring cloud config 管理中心启动

    Config 工程创建之后,Eureka就可以使用Git上的配置启动服务了. Git 服务器的搭建这里就不细说了(自行解决),下面是我上传再git的配置文件: 创建EurekaServer项目(eur ...

  3. 第二章 Internet 地址结构

    注意: 这个系列的博客只是为了巩固我学习的知识,参考的价值不是很大,如果需要,请转到http://www.cnblogs.com/ZCplayground/p/7764436.html Interne ...

  4. J2EE的十三个技术——JSP

    简介 JSP,Java Server  Page,Java服务器页面.它是在传统的网页HTML文件中插入Java程序段(Scriptlet)和JSP标记,从而形成JSP文件,后缀名为(*.jsp). ...

  5. PHP面向对象关键词static 、self

    知识点: 一.static可以修饰类内的属性或方法,被修饰的属性或方法在类外部,不能被实例化成对象访问,而是使用类本身进行访问,而静态的方法如果想使用静态的属性,则需要用self::这样的写法来访问静 ...

  6. 【bzoj3444】最后的晚餐 并查集

    题目描述 n个人排成一排,有m个条件,第i个条件要求ai和bi相邻,求方案数. 输入 输入有m+1行,第一行有两个用空格隔开的正整数n.m,如题所示.接下来的m行,每一行有两个用空格隔开的正整数,第i ...

  7. 树(tree)

    树(tree) 题目描述 小明正在研究一种砍树游戏.一开始在W列H行的方格上,每一个格子都长着一颗树,格子的行从北到南依次编号,格子的列从西到东依次编号. 小明会砍倒一些树,每砍倒一颗树,树会占据这个 ...

  8. Codeforces Round #359 (Div. 2) B

    B. Little Robber Girl's Zoo time limit per test 2 seconds memory limit per test 256 megabytes input ...

  9. Codeforces Round #324 (Div. 2) A

    A. Olesya and Rodion time limit per test 1 second memory limit per test 256 megabytes input standard ...

  10. npm下载包失败的几个原因

    1. 可能是由于网络问题导致下载包失败,因为qiang,所以,直接使用npm有些情况会导致下载包失败,使用cnpm源或者yarn下载等方法可以解决这个问题. 2. 这个包不存在,检查一下包的拼写或者路 ...