用于类似 Google 建议的字典






4.90/5 (11投票s)
2005年6月6日
3分钟阅读

58544

1153
创建一个可以像Google Suggest字典一样工作的字典。
引言
当我阅读由Gavi Narra撰写的Google Suggest字典文章时,我发现那个字典是HTML纯文本格式的,需要将其转换为数据库表。
这些数据来自一个免费的在线字典(一个公共领域的英语单词列表字典,基于《古登堡计划》的《韦氏大学词典》的公共领域部分,该部分又基于1913年的美国《韦氏大学词典》。你可以在这里下载)。
我构建了一个小型VB.NET应用程序,可以将这些HTML文件及其中的数据转换为有意义的数据库表。
使用代码
转换成功需要两个步骤
- 将HTML文件转换为字符分隔值。
- 处理分隔值以生成
INSERT INTO
语句。
我使用MS Access数据库来保存结果,但我认为使用MS SQL在转换过程中以及作为字典都是更合适的。
第一步(创建基础)
基础是将HTML纯文本转换为分隔值(CSV)的结果。HTML文件包含纯文本字典,如下所示
Islam (n.) The religion of the Mohammedans; Mohammedanism;
Islamism. Their formula of faith is: There is no God but Allah,
and Mohammed is his prophet.
必须以某种方式将其转换为可读格式并插入数据库。最好的方法是使用字符分隔值,如下所示
Islam@(n.)@The religion of the Mohammedans; Mohammedanism;
Islamism. Their formula of faith is: There is no God but Allah,
and Mohammed is his prophet.
其中@是用作字段分隔符的字符。数据库插入后的结果将是
Dict | |
单词 |
Islam |
类型 |
(n.) |
平均 |
伊斯兰教;穆斯林宗教;伊斯兰主义。他们的信仰格言是:万物非主,唯有安拉;穆罕默德是安拉的使者。 |
该项目将运行的流程是 HTML ----第一步----> CSV ----第二步----> 数据库。
从HTML到CSV的代码转换位于按钮的Click
事件中。HTML文件包含一些不需要的标签,可以用作转换的提示。txtpath2
文本框是HTML文件路径,而txtpathtarget
文本框是目标文件路径,可以是任何扩展名。使用IO.StreamReader
打开txtpath2
中指定的名称文件,然后用@字符替换一些标签,然后将文件保存在另一个位置,这是此步骤的核心操作。
Private Sub Button2_Click(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles Button2.Click
progbar2.Value = 0
Dim myfile = New IO.StreamReader(txtpath2.Text)
Try
'---Proceesing the file that contain delimited contents
Dim Line As String
Line = myfile.Readtoend
'----Remove unwanted tags
Line = Line.Replace("<P>", "")
progbar2.Value += 1
Line = Line.Replace("</P>", "")
progbar2.Value += 1
Line = Line.Replace("<B>", "")
progbar2.Value += 1
Line = Line.Replace(" (<I></I>) ", "@")
progbar2.Value += 1
Line = Line.Replace("</B>", "@")
progbar2.Value += 1
Line = Line.Replace(" (<I>", "")
progbar2.Value += 1
Line = Line.Replace("</I>) ", "@")
progbar2.Value += 1
Dim myfileSave As New IO.StreamWriter(txtpathtarget.Text, True)
myfileSave.Write(Line)
myfileSave.Close()
progbar2.Value += 1
MessageBox.Show("Substrate completed successfully", _
"Dict Maker")
Catch ex As IO.IOException
MessageBox.Show("Error: " & ex.Message, "Critical error", _
MessageBoxButtons.OK, MessageBoxIcon.Error)
Catch ex As Exception
MessageBox.Show("Error: " & ex.Message, "Critical error", _
MessageBoxButtons.OK, MessageBoxIcon.Error)
Finally
myfile.Close()
End Try
End Sub
正如你所看到的,应该创建一个包含CSV的目标文件。这个文件将在第二步中用于生成INSERT INTO
语句。
第二步(绑定到酶)
一旦你完成了将HTML文件转换为CSV文件,你就可以进一步从CSV文件中生成所需的INSERT INTO
语句。在此步骤中,你将指定由第一步制作的CSV文件。
此步骤包括打开数据库连接,生成SQL命令,使用IO.StreamReader
逐行处理CSV,并执行命令。txtpath
文本框包含CSV文件路径。我使用了split
函数,该函数识别字符串中由数组(@)中指定的一个或多个字符分隔的子字符串,然后将子字符串放入一个String
数组。
返回的数组的上限为2(3个元素),分别为0-1-2。数组元素分别是单词、类型和含义。将为每个值生成一个SQL语句。由于我使用的是MS Access数据库,命令需要逐个执行。如果你将数据库更改为MS SQL,你可以生成INSERT INTO
语句,然后一次性执行它们,因为MS SQL服务器支持批处理或多查询。这将提高应用程序的性能。
转换过程附带进度条,其最大值由CalculateEstimate
函数提供,该函数将循环遍历CSV文件以计算将要处理的行数。
注意:不要忘记在连接字符串中指定数据源路径,否则应用程序将无法工作。
Private Sub Button1_Click(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles Button1.Click
ProgBar.Value = 0
If txtpath.Text = "" Then Exit Sub
MsgBox(txtpath.Text)
'-----Open the connection
Dim con As New OleDb.OleDbConnection
Dim com As New OleDb.OleDbCommand
'------
con.ConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;" & _
"Data Source=d:\vbprograms\dictmaker\dict.mdb"
'----calculate estimates and set the progress bar
ProgBar.Maximum = CalculateEstimate(txtpath.Text)
'----
Dim myfile = New IO.StreamReader(txtpath.Text)
Try
'--open the database
con.Open()
'---Proceesing the file that contain delimited contents
Dim Line As String
Dim AfterSep() As String
'--------------------Ignore the first 9 lines
For t As Integer = 1 To 9
myfile.ReadLine()
Next t
'--------------------
While myfile.Peek > -1
Application.DoEvents()
Line = myfile.ReadLine()
If Line = "</BODY>" Then Exit While
'----If the carriage return, request next line
If Line = "" Then Line = myfile.ReadLine()
AfterSep = Line.Split("@"c)
'----Build the command and executeit
com.Connection = con
com.CommandText = _
"INSERT INTO dict (word,type,mean) VALUES (?,?,?)"
com.Parameters.Clear()
com.Parameters.Add("?", AfterSep(0))
com.Parameters.Add("?", AfterSep(1))
com.Parameters.Add("?", AfterSep(2))
com.ExecuteNonQuery()
'----Set value progress
' If ProgBar.Value = 5136 Then Stop
ProgBar.Value += 1
lblprocessed.Text = "Line(s) processed : " & ProgBar.Value
End While
MessageBox.Show("Conversion completed successfully", "Dict Maker")
Catch ex As OleDb.OleDbException
MessageBox.Show("Error: " & ex.Message, _
"Critical error", MessageBoxButtons.OK, _
MessageBoxIcon.Error)
Catch ex As IO.IOException
MessageBox.Show("Error: " & ex.Message, _
"Critical error", MessageBoxButtons.OK, MessageBoxIcon.Error)
Catch ex As Exception
MessageBox.Show("Error: " & ex.Message, _
"Critical error", MessageBoxButtons.OK, MessageBoxIcon.Error)
Finally
con.Close()
myfile.Close()
End Try
End Sub
计算将要处理的行数
Function CalculateEstimate(ByVal path As String) As Integer
Dim estimate As New IO.StreamReader(path)
Dim NumOfLines As Integer
While estimate.Peek > -1
estimate.ReadLine()
NumOfLines += 1
End While
estimate.Close()
lblTotalLines.Text = "Total Line(s): " & NumOfLines - 11
Return NumOfLines
End Function
最后
尽管VS2005 ASP 2.0已经覆盖了Gavi Narra所写的想法(HttpXmlRequest
),但他的工作确实很棒,我希望我的工作能起到补充作用。
此致。