65.9K
CodeProject 正在变化。 阅读更多。
Home

用于类似 Google 建议的字典

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.90/5 (11投票s)

2005年6月6日

3分钟阅读

viewsIcon

58544

downloadIcon

1153

创建一个可以像Google Suggest字典一样工作的字典。

Sample Image

引言

当我阅读由Gavi Narra撰写的Google Suggest字典文章时,我发现那个字典是HTML纯文本格式的,需要将其转换为数据库表。

这些数据来自一个免费的在线字典(一个公共领域的英语单词列表字典,基于《古登堡计划》的《韦氏大学词典》的公共领域部分,该部分又基于1913年的美国《韦氏大学词典》。你可以在这里下载)。

我构建了一个小型VB.NET应用程序,可以将这些HTML文件及其中的数据转换为有意义的数据库表。

使用代码

转换成功需要两个步骤

  1. 将HTML文件转换为字符分隔值。
  2. 处理分隔值以生成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),但他的工作确实很棒,我希望我的工作能起到补充作用。

此致。

© . All rights reserved.