日期:2011-10-06  浏览次数:20916 次

本文将为你提供了一个强大而灵活的方法,旨在从现有的HTML文件中提取并组合成有意义的数据。

HTML和Web已经永远地改变了人们通信与沟通的方式,HTML对人们来说很方便,它使得信息更易于查看和航行,但遗憾的是,它对计算机之间的交流就远远没有那么方便了:Web页面上由于层的实现代码,使得计算机系统都难以找到和使用数据。这时,XML应运而生,它承诺要对计算机系统之间通信的方式起到同样的作用,XML将成为信息在不同计算机系统之间流动的公用语言。应用本文中介绍的简单编程技术,你可以将任何HTML页面转换成一个XML数据源。

例程说明
想象有一个花店,每个星期都要根据价格从3个鲜花批发商中的一个进货。每个星期,店主都要查看每个批发商的Web站点来找到最低的价格。店主想把这三个批发商的价格信息都组合到一个Web页面中来简化他搜索的过程。

下面就示范如何从3个Web页面中提取信息并且将它们结合到一个单一的XML文档中。我们为这个例子创建了3个鲜花批发商的页面:

<>
<>
<>

出于示范目的,每次访问页面时,每个页面上的价格都会改变。另外,由于Web页面经常会把相关数据放在HTML表格中,样本页面和应用程序将着重从表格中而不是从其它标记中恢复信息。

解决方案
下表包含了一个含有你需要的数据的样本XML文件Flowers.xml:

<Flowers><Flower><Vendor>FakeFlowers</Vendor><Name>Daffodil</Name>
<Price>$2.00</Price></Flower>
<Flower><Vendor>FictitiousFlowers</Vendor><Name>Daffodil</Name><Price>$5.00</Price>
</Flower>
<Flower><Vendor>PretendFlowers</Vendor>
<Name>Daffodil</Name><Price>$3.50</Price></Flower>
</Flowers>


现在你需要编写代码,直接从相应的批发商Web站点中提取鲜花的名称和价格。一个解决方案是在XML文档中放置特殊的标记,以后用站点中的值来代替。这种方法与XSL相同。要想这样做,你可以定义一个新的元语言,它可让你向XML中增加可替换的标记。
这个新的元语言需要完成以下任务:

识别文档,以便知道它是在使用这个语言
提供一个方法,以指定包含着你想恢复数据的Web页面
指定如何从每个页面恢复特定的数据元素。下面的例子提取前一个XML文件,并且包含了新的元语言标记来完成上面所列举的3个目标:
<WG:Documentxmlns:WG="">
<Flowers>
<WG:Templateurl="">
<Flower>
<Vendor>FakeFlowers</Vendor>
<Name><WG:GetTableElementpos="1"row="8"col="1"/></Name>
<Price><WG:GetTableElementpos="1"row="8"col="4"/></Price>
</Flower>
</WG:Template>
<WG:Templateurl="">
<Flower>
<Vendor>FictitiousFlowers</Vendor>
<Name><WG:GetTableElementpos="1"row="6"col="2"/></Name>
<Price><WG:GetTableElementpos="1"row="6"col="3"/></Price>
</Flower>
</WG:Template>
<WG:Templateurl="">
<Flower>
<Vendor>PretendFlowers</Vendor>
<Name><WG:GetTableElementpos="1"row="3"col="1"/></Name>
<Price><WG:GetTableElementpos="1"row="3"col="4"/></Price>
</Flower>
</WG:Template>
</Flowers>
</WG:Document>

第二个XML例子有一个包裹元素叫做Document,放置在原始XML的两头。Document元素为这个叫做WebGather的新元语言定义了名称空间。WebGatherSchema.xml文件中定义了WebGather语言元素:

<!—WebGatherschema-->
<Schemaxmlns="urn:schemas-microsoft-com:xml-data">
<elementtype='Document'>
<elementtype='Template'>
<attributetype='url'/>
<elementtype='GetTableElement'>
<attributetype='pos'/>
<attributetype='row'/>
<attributetype='col'/>
</element>
</element>
</element>
</Schema>

WebGatherschema允许使用三种类型的XML元素:Template(模板)元素只有一个属性"URL",它定义了包含数据的源Web页面。GetTableElement标记是一个在Template元素中定义的页面内表格中一个单元的内容占位符。GetTableElement标记有三个属性,第一个属性叫做"pos",它定义了HTMLWeb页面中表格元素的索引号,其中第一个表格就是1;"row"和"col"属性定义了包含数据的表格中的单元。

具体实现
元语言需要执行才能起作用。我使用了一个VisualBasicDLL工程文件,其中只包含了一个类叫做MetaGather。这个类使用了一个公共方法,叫做Transform,它接收一个XML字符串,其中包含WebGather标记,它取代带有来自指定Web页面值的那些标记,生成XML字符串。这个类使用了MicrosoftInternetExplorer控件来恢复Web页面,并从XML字符串参数中的Template标记中读取包含数据的页面URL。

PrivateFunctionLoadPage_
(ByValstrURLAsString)AsBoolean
'Initializethedownloadcompleteflag
m_bDownloadComplete=False

'Loadthepagetomakesureits
'notthecachedversion
m_IE.NavigatestrURL,4

'Waituntildocumentfinishesloading
Whilem_IE.ReadyState<>READYSTATE_COMPLETE
DoEvents
Wend

'Checkifyouendedupontheerrorpage
Ifm_IE.Document.Title=_
"Thepagecannotbefound"Or_
m_IE.Document.Title="Nopagetodisplay"_
Then
LoadPage=False
Else
LoadPage=True