@"<tr bgcolor='#\w+' ><td height='20'>(?<currency>.*)</td>\s*" +
@"<td height='20'><p align='right'>(?<bankbuytt>\d*.?\d*)( )+.?</td>\s*" +
@"<td height='20'><p align='right'>(?<buynotes>\d*.?\d*)( )+.?</td>\s*" +
@"<td height='20'><p align='right'>(?<sell>\d*.?\d*)( )+.?</td>\s*" +
@"<td height='20'><p align='right'>(?<base>\d*.?\d*)( )+.?</td>\s*"
using System;
using System.Collections;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Web;
using System.Net;
using System.Web.Services;
using System.Xml;
using System.Text;
using System.Text.RegularExpressions;
using System.IO;
namespace ChinaBank
{
/// <summary>
/// Summary description for ForeignExchange.
/// </summary>
[WebService(Namespace="http://dancefires.com/ChinaBank/")]
public class ForeignExchange : System.Web.Services.WebService
{
public ForeignExchange()
{
//CODEGEN: This call is required by the ASP.NET Web Services Designer
InitializeComponent();
}
#region Component Designer generated code
//Required by the Web Services Designer
private IContainer components = null;
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
}
/// <summary>
/// Clean up any resources being used.
/// </summary>
protected override void Dispose( bool disposing )
{
if(disposing && components != null)
{
components.Dispose();
}
base.Dispose(disposing);
}
#endregion
[WebMethod]
public XmlDataDocument GetForeignExchangeRates()
{
return getXmlDoc();
}
[WebMethod]
public DataSet GetForeignExchangeRatesDataSet()
{
return getXmlDoc().DataSet;
}
[WebMethod]
public string GetBankPage()
{
return getWebContent( "http://www.bank-of-china.com/info/whjrpj.html" );
}
// private methods
private string getWebContent( string url )
{
using( WebClient client = new WebClient() )
{
byte[] buffer = client.DownloadData( url );
string str = Encoding.GetEncoding("GB2312").GetString( buffer, 0, buffer.Length );
return str;
}
}
private XmlDataDocument getXmlDoc()
{
string webcontent = getWebContent("http://www.bank-of-china.com/info/whjrpj.html");
// Prepair for DataSet
DataSet ds = new DataSet("Exchange");
DataTable dt = new DataTable("ForeignExchange");
ds.Tables.Add( dt );
dt.Columns.Add( "Currency", typeof(string) );
dt.Columns.Add( "BankBuyTT", typeof(double) );
dt.Columns.Add( "BankBuyNotes", typeof(double) );
dt.Columns.Add( "BankSell", typeof(double) );
dt.Columns.Add( "Baseline", typeof(double) );
XmlDataDocument xmldoc = new XmlDataDocument( ds );
Regex expr = new Regex(
@"<tr bgcolor='#\w+' ><td height='20'>(?<currency>.*)</td>\s*" +
@"<td height='20'><p align='right'>(?<bankbuytt>\d*.?\d*)( )+.?</td>\s*" +
@"<td height='20'><p align='right'>(?<buynotes>\d*.?\d*)( )+.?</td>\s*" +
@"<td height='20'><p align='right'>(?<sell>\d*.?\d*)( )+.?</td>\s*" +
@"<td height='20'><p align='right'>(?<base>\d*.?\d*)( )+.?</td>\s*"
, RegexOptions.Compiled);
for( Match m = expr.Match(webcontent) ; m.Success ; m=m.NextMatch() )
{
string key;
DataRow row = dt.NewRow();
row["Currency"] = m.Groups["currency"];
key = m.Groups["bankbuytt"].ToString();
row["BankBuyTT"] = key.Length > 0 ? Convert.ToDouble( key )/100 : 0;
key = m.Groups["buynotes"].ToString();
row["BankBuyNotes"] = key.Length > 0 ? Convert.ToDouble( key )/100 : 0;
key = m.Groups["sell"].ToString();
row["BankSell"] = key.Length > 0 ? Convert.ToDouble( key )/100 : 0;
key = m.Groups["base"].ToString();
row["Baseline"] = key.Length > 0 ? Convert.ToDouble( key )/100 : 0;
dt.Rows.Add( row );
}
return xmldoc;
}
}
}
客户端也很容易,只要用wsdl生成了相应的WebService Proxy后,直接调用就行了,由于我让Server端返回了DataSet,因此客户端直接用DataGrid来显示DataSet即可,非常Easy,在这个问题上客户端没有什么技术关键点。
using System;
using System.Threading;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
namespace BankDataClient
{
/// <summary>
/// Summary description for frmMainBankRates.
/// </summary>
public class frmMainBankRates : System.Windows.Forms.Form
{
private System.Windows.Forms.DataGrid dataGrid1;
private System.Windows.Forms.Button btnConnect;
private System.Data.DataSet ds;
private BankDataClient.com.dancefires.[url]www.ForeignExchange[/url] proxy = new BankDataClient.com.dancefires.www.ForeignExchange();
private System.Windows.Forms.TextBox txtUrl;
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.Container components = null;
public frmMainBankRates()
{
//
// Required for Windows Form Designer support
//
InitializeComponent();
try
{
txtUrl.Text = System.Configuration.ConfigurationSettings.AppSettings["url"];
proxy.Url = txtUrl.Text;
}
catch(Exception)
{
proxy.Url = "http://www.dancefires.com/ChinaBank/ForeignExchange.asmx";
txtUrl.Text = proxy.Url;
}
}
/// <summary>
/// Clean up any resources being used.
/// </summary>
protected override void Dispose( bool disposing )
{
if( disposing )
{
if(components != null)
{
components.Dispose();
}
}
base.Dispose( disposing );
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.dataGrid1 = new System.Windows.Forms.DataGrid();
this.ds = new System.Data.DataSet();
this.btnConnect = new System.Windows.Forms.Button();
this.txtUrl = new System.Windows.Forms.TextBox();
((System.ComponentModel.ISupportInitialize)(this.dataGrid1)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.ds)).BeginInit();
this.SuspendLayout();
//
// dataGrid1
//
this.dataGrid1.DataMember = "";
this.dataGrid1.DataSource = this.ds;
this.dataGrid1.HeaderForeColor = System.Drawing.SystemColors.ControlText;
this.dataGrid1.Location = new System.Drawing.Point(32, 48);
this.dataGrid1.Name = "dataGrid1";
this.dataGrid1.Size = new System.Drawing.Size(480, 256);
this.dataGrid1.TabIndex = 0;
//
// ds
//
this.ds.DataSetName = "Exchange";
this.ds.Locale = new System.Globalization.CultureInfo("zh-CN");
//
// btnConnect
//
this.btnConnect.Location = new System.Drawing.Point(432, 16);
this.btnConnect.Name = "btnConnect";
this.btnConnect.TabIndex = 1;
this.btnConnect.Text = "连接";
this.btnConnect.Click += new System.EventHandler(this.btnConnect_Click);
//
// txtUrl
//
this.txtUrl.Location = new System.Drawing.Point(32, 16);
this.txtUrl.Name = "txtUrl";
this.txtUrl.Size = new System.Drawing.Size(384, 20);
this.txtUrl.TabIndex = 2;
this.txtUrl.Text = "";
//
// frmMainBankRates
//
this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
this.ClientSize = new System.Drawing.Size(544, 318);
this.Controls.Add(this.txtUrl);
this.Controls.Add(this.btnConnect);
this.Controls.Add(this.dataGrid1);
this.Name = "frmMainBankRates";
this.Text = "Foreign Exchange Rates of Bank of China";
((System.ComponentModel.ISupportInitialize)(this.dataGrid1)).EndInit();
((System.ComponentModel.ISupportInitialize)(this.ds)).EndInit();
this.ResumeLayout(false);
}
#endregion
private void btnConnect_Click(object sender, System.EventArgs e)
{
UpdateDataGrid();
}
private void UpdateDataGrid()
{
try
{
btnConnect.Enabled = false;
txtUrl.ReadOnly = true;
proxy.Url = txtUrl.Text;
ds = proxy.GetForeignExchangeRatesDataSet();
dataGrid1.SetDataBinding( ds, "ForeignExchange" );
dataGrid1.Update();
}
catch( Exception err )
{
MessageBox.Show( err.Message );
}
finally
{
txtUrl.ReadOnly = false;
btnConnect.Enabled = true;
}
}
[STAThread]
static void Main( string[] args )
{
Application.Run( new frmMainBankRates() );
}
}
}
有了这个例子,应该可以从中了解最基本的XML, WebService, Regular Expression, DataSet, DataGrid的知识。
软件所有代码,及相关截屏可以从下面的连接中获得:
http://www.dancefires.com/ChinaBank/