将Web页面转换成XML数据源

80酷酷网    80kuku.com

  web|xml|数据|数据源|页面|转换本文将为你提供了一个强大而灵活的方法,旨在从现有的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
EndIf
EndFunction

LoadPage函数调用MicrosoftInternet控件的Navigate方法从Internet中取回页面内容。Navigate工作方式是不同步的,因此在继续之前必须要等待页面装载。这可以通过使用一个循环以等待一个模块级别的标志设置完成来实现。DownloadComplete事件被激活时,这个标志就被设置。通常Navigate方法被调用时,DownloadComplete事件就被激活。这样一来,即使是导航失败,也能保证这个标志最终会被设置为真,然后我们就退出循环。

分享到
  • 微信分享
  • 新浪微博
  • QQ好友
  • QQ空间
点击: