解析HTML文件 - 运用SgmlReader类来解析HTML文件

运用.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文件

时间: 2024-10-27 11:24:53

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

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

一 CodeSmith简介 本文以表自动生成NHibernate的映射文件和映射类的实例来说明一下本软件的使用方法. CodeSmith是一种基于模板的代码生成工具,其使用类似于ASP.NET的语法来生成任意类型的代码和文件.使用 CodeSmith,可以生成包括简单的强类型集合和完整应用程序在内的任何东西.(弱类型-没有明显的类型,会随着环境的不同自动变换类型:强类型-在声明时规定其数据类型,保证类的安全,虽然系统也有一定的默认转换,但是没有弱类型那么随便) 当您生成应用程序时,您经常需要重复

ORM利器:NHibernate(二)使用CodeSmith快速生成映射文件和映射类

    在上一篇文章<ORM利器:NHibernate(一)简介>,我们对NHibernate做了简要介绍,接下来的系列文章将以Demo的形式和大家分享使用NHibernate的初步使用. 一 CodeSmith简介 本文以表自动生成NHibernate的映射文件和映射类的实例来说明一下本软件的使用方法.     CodeSmith是一种基于模板的代码生成工具,其使用类似于ASP.NET的语法来生成任意类型的代码和文件.使用 CodeSmith,可以生成包括简单的强类型集合和完整应用程序在内的

DuiLib 源码分析之解析xml类CMarkup &amp; CMarkupNode 头文件

xml使用的还是比较多的,duilib界面也是通过xml配置实现的 duilib提供了CMarkkup和CMarkupNode类解析xml,使用起来也是比较方便的,比较好奇它是怎么实现的,如果自己来写一个 解析又需要怎样架构,架构之路还很遥远... 先来看看头文件吧,CMarkup主要是用于分割xml,判断xml格式是否正确:CMarkupNode主要是将CMarkup分割的xml,获取节点中的属性, 最多支持64个属性 1 enum 2 { 3 XMLFILE_ENCODING_UTF8 =

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

1.android下junit测试框架配置 单元测试需要在手机中进行安装测试 (1).在清单文件中manifest节点下配置如下节点 <instrumentation android:name="android.test.InstrumentationTestRunner" android:targetPackage="com.example.demo1" /> 上面targetPackage指定的包要和应用的package相同. (2)在清单文件中ap

文件上传漏洞及解析漏洞总结

文件上传漏洞是指用户上传了一个可执行的脚本文件,并通过此脚本文件获得了执行服务器端命令的能力.这种攻击方式是最为直接和有效的,"文件上传"本身没有问题,有问题的是文件上传后,服务器怎么处理.解释文件.如果服务器的处理逻辑做的不够安全,则会导致严重的后果. 文件上传后导致的常见安全问题一般有: 1)上传文件是Web脚本语言,服务器的Web容器解释并执行了用户上传的脚本,导致代码执行. 2)上传文件是Flash的策略文件crossdomain.xml,黑客用以控制Flash在该域下的行为(

Tomcat源码分析——server.xml文件的加载与解析

前言 作为Java程序员,对于tomcat的server.xml想必都不陌生.本文基于Tomcat7.0的Java源码,对server.xml文件是如何加载和解析进行分析. 加载过程分析 Bootstrap的load方法用于加载tomcat的server.xml,实际是通过反射调用Catalina的load方法,代码如下: /** * Load daemon. */ private void load(String[] arguments) throws Exception { // Call

zend framework2 之入口文件详解以及原理解析

zend framework2 之入口文件详解 转载请注明出处,尊重原创:http://blog.csdn.net/a437629292/article/details/41545297,谢谢! 一.基本配置解析 1. 详细配置: 如下代码: <?php // 定义程序目录 defined('APPLICATION_PATH') || define('APPLICATION_PATH', realpath(dirname(__FILE__) . '/../application')); // D

C#之Socket操作类实例解析

本文展示了一个C#的Socket操作类的完整实例,并附带了用法说明,分享给大家供大家参考之用.具体方法如下: 主要功能代码如下: using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Net.Sockets; using System.Collections; using System.Net; using System.Runtime.Serializ

【并发】5、多线程并发解析单文件大数据了量解析入库,1800万数据8线程5分钟入库

1.首先机器要求8核,不然可能会慢点 2.数据库建表的时候,最后建那种nologging类型的表,不然归档日志满了,数据库入库会很慢,甚至丢数据,因为数据量很大,我们不可能一次性提交所有数据,只能分批提交 package com.ztesoft.interfaces.predeal.util; import com.ztesoft.interfaces.predeal.bl.IHandle; import java.io.ByteArrayOutputStream; import java.io