在 Java 应用程序中使用 Java 字典和辞典 API
级别: 中级
Rakesh Midha (mrakesh@in.ibm.com)
软件工程师, IBM 软件试验室,Bangalore
2004 年 10 月
Java 字典和辞典 API(Dictionary and Thesaurus API for Java,JADT)是 Java 应用程序中访问语言特性的一个类库。本文是由两部分组成的系列文章的第 1 部分,在本文中,JADT 开发人员 Rakesh Midha 从用户的角度讨论了 JADT,并展示了如何在 Java 应用程序里使用 JADT。他讨论了 JADT 中涉及的各种不同的类和设计,以及 JADT 中可以使用的一些特性。第 2 部分则深入讨论体系结构和 API 的细节,为那些希望实现 JADT 驱动程序的用户提供指导。
Java 字典和辞典 API(JADT)是 alphaWorks 上发布的辞典特性的 API,是一个基于标准的类库,用于在 Java 应用程序里访问语言特性。它为 Java 程序员提供了透明的以 Java 为中心的方法,用以访问字典和非结构化单词,以及有关它们的信息。本文是由两部分组成的系列文章的第 1 部分,涉及的内容是用 JADT 开发增强字典和辞典的 Java 应用程序。第 2 部分提供了对体系结构和 API 的详细考察。
JADT 概述
JADT 是用于从 Java 编程语言中访问辞典数据的 API。它提供了可以在 Java 应用程序中使用的通用接口,独立于字典/数据提供者的实现。使用 JADT,用 Java 语言编写的应用程序就可以访问某个具体单词的定义、发音、同义词、反义词等信息。
JADT 的特性包括:
访问字典、辞典和其他服务的接口
多语言转换接口
基于驱动程序的访问协议
用于字典提供者和驱动程序开发人员的 API
访问后端字典或辞典,比如数据库、文件系统或基于 XML 的文件(只要实现了它们的驱动程序)
JADT 对于辞典数据访问应用程序来说是一个非常有用的 API,因为它为执行这类任务提供了简单的、标准的技术。它把应用程序开发人员 从维护数据和数据访问点的痛苦中解救出来。
对于很多使用多语言特性、本地化和类似特性的应用程序来说,这个 API 的实现会非常有用。例如,在编辑的时候,编辑可以用这个技术进行拼写检查,或者得到更多合适单词的建议。另一个示例应用可能是,让需要翻译的应用程序可以使用多语言字典和辞典。
除此之外,JADT 还提供了语言中立的接口,这让它可以用于各种语言和方言。而且,由于 ADT 是用 Java 语言编写的,它的示例驱动程序也是用 Java 语言实现的,所以它是平台无关的。
JADT 数据结构
JADT 包括各种不同的组件和服务,取决于所使用的 JADT 的特性或具体的子集。您的 JADT 旅程的第一站,是一组提供数据组织的一般方法的类和接口。 因为所有服务都使用这些数据结构,所以 JADT 用户对它们的了解,是非常重要的。
单词列表
WordList 类就是一个单词的容器。它不从后端资源取数据。WordList 一般用于传递、取得或包含成组的单词。除此之外,还有一个选项,用于查找符合特定规则的所有单词。例如,它目前支持查找带有相似前缀或后缀的单词,支持共享某些子串的单词查找。它与 WordLister 服务不同,因为它不从后台资源取词,所以它仅仅是一个包装类。它还可以用于单词集合,如清单 1 所示:
清单 1. Wordlist 作为集合的用法
WordList wordlist= wordlister.findWithPrefix("un");
//Getting collection of words one by one
wordlist.start();
while(wordlist.hasMoreWords())
{
Word word=wordlist.getNext();
}
// Using WordList further to narrow down the search
WordList wordlist2= wordlist.findWithSuffix("ing");
单词
Word 接口代表语言单元或者母语使用者能够识别的字符构成。 Word 把单词的信息包装起来。保存在 Word 里的信息包括单词拼写、类型、来源、发音和记录。一旦从某项服务得到了 word 对象,就可以方便地用它的方法来提取信息,如清单 2 所示:
清单 2. 用 word 提取数据
Word word=wordlist.getNext();
String strName=word.getWord();
字典记录
DictionaryRecord 对象保存单词的附加信息。 DictionaryRecord 通常被用来表示 JADT 驱动程序实现的某项服务获得的单词结果集。记录中保存着单词的信息,例如它的描述、类型、用法、区域、发音等等。因为 DictionaryRecord 是作为 chainedObject 实现的,所以能够以串接对象的形式,用 chainedObject 来取得多组单词信息。可以把这项技术用于某一服务的结果集,如清单 3 所示:
清单 3. DictionaryRecord 的用法
DictionaryRecord dr= dict.getMeaning("dictionary");
dr.start();
while(dr!=null)
{
String strName=dr.getWordName();
String pronunciation=dr.getPronunciation();
String type= dr.getType();
String meaning=dr.getDescription();
dr=dr.getNextRecord();
}
JADT 驱动程序
就像我前面说过的,JADT 提供了基于驱动程序的访问机制,所以 Java 应用程序可以独立于实现提供者工作。为了做到这一点,JADT 驱动程序需要能够与正在访问的具体数据源进行通信。可以通过某个驱动程序服务,把用户调用发布给数据源,还可以把这些语句的结果发回用户。
实现提供者负责 JADTDriver,JADT 驱动程序则负责为您提取并提供您所需要的数据。
JADT 带有两个缺省驱动程序,用于与 JADT API 绑定的两种不同数据源。这两个驱动程序是 JADTTextDriver,它针对以文本格式保存的语言数据来实现,JADTXMLDriver,它针对以 XML 格式保存的语言数据来实现。
控制流程
JADT API 定义了访问 JADTDriver 服务的编程模型,Java 应用程序开发人员必须按照协议来使用 JADTDriver。所以 JADT 服务访问代码的最简单流程必须是:
载入 JADTDriverFactory:当调用 Class.forName("com.ibm.jadtdrivers.TextDriver.JADTTextDriverFactory"); 载入 JADTDriverFactory 的时候,JADTDriverFactory 会自动注册到驱动程序上。
从 JADTDriverFactoryManager 获得 JADTDriverFactory:JADTDriverFactory是各种驱动程序的生产工厂,一直由 JADTDriverFactoryManager 控制。所以可以调用 JADTDriverFactory fac=JADTDriverFactoryManager.getJADTDriverFactory("JADTTextDriverFactory");,用 JADTDriverFactoryManager 获得 JADTDriverFactory。
生成 JADT 驱动程序 :JADT 驱动程序 提供了对各种服务的访问,例如字典、辞典、拼写检查、单词表、翻译器、语法检查器和词变位器。可以调用工厂的 createJADTDriver() 方法来创建它:
Driver dri =fac.createJADTDriver();
设置驱动程序的属性:驱动程序属性由驱动程序提供者公布。例如,对于文本和 XML 驱动程序非常重要的是,用户需要设置到达数据目录的路径,可以用 driver.setProperty("JADTTextDriverDir","c:\\datadir"); 完成。如果没有设置这个路径,就会采用缺省值,缺省值是驱动程序类的路径。
现在,您就可以开始使用驱动程序支持的所有语言的驱动程序服务了。
访问字典
字典是 JADT 驱动程序提供的最重要的服务之一,文本和 XML 驱动程序都支持这项服务。可以用下面的语句,从驱动程序得到特定语言的字典:
Dictionary dict=driver.getDictionary("english","english");
getMeaning() 方法为您指定的每个单词提取 DictionaryRecord,里面包含单词的多个含义。清单 4 显示了字典的用法:
清单 4. 字典的用法
DictionaryRecord dr= dict.getMeaning("dictionary");
dr.start();
while(dr!=null)
{
String strName=dr.getWordName();
String pronunciation=dr.getPronunciation();
String type= dr.getType();
String meaning=dr.getDescription();
dr=dr.getNextRecord();
}
使用辞典
WordBook 是提供相关单词分类列表的服务组件,它提供了所有相关单词的信息。这些单词可以按照用法、来源、发音等指标关联起来。
可以用以下代码从驱动程序访问这项服务:
WordBook wordbook=driver.getWordBook("english");
文本和 XML 驱动程序都支持这项服务。
JADT 的当前版本提供了实现以下服务的接口:
同义词
同义词(Synonyms)是指在给定上下文中可以互换使用的两个单词。有两个方法提供这项服务:
getSynonyms() 用来取得同义词。
isSynonyms() 用来判断两个单词是否同义词。
清单 5 显示了使用的方法:
清单 5. 检查同义词的辞典用法
DictionaryRecord dr= this.wordbook.getSynonyms("dictionary");
while(dr!=null)
{
String strName=dr.getWordName();
dr=dr.getNextRecord();
}
if(wordbook.isSynonyms("dictionary","lexicon"))
{
/*..*/
}
本节里的其他服务也可以使用同样的技术,所以我就不为每项服务都演示了。
反义词
反义词(Antonyms )是指意义相反的两个单词。使用 WordBook,您可以检查单词是否意义相反,也可以找到单词的所有反义词。同样,也有两个方法提供这项服务:
getAntonyms() 用来取得反义词。
isAntonyms() 用来判断两个单词是不是意义相反。
上位词
上位词(Hypernyms )是指范围大或一般性概念的单词。“Computer”或“fruit”相对于更具体的术语(例如“Dell”或“banana”)来说,就是上位词。您可以用 WordBook 来获得所有的上位词,或者检测单词是否为上位词。有两个方法提供这项服务:
getHypernym() 用来取得上位词
isHypernym() 用来判断两个单词是否上位词
下位词
下位词(Hyponyms)是指更加具体的单词或概念的单词。专有名词就是下位词的好例子。“North America”或“Mercedes”是“continent”或“automobile”的下位词。
您可以用 WordBook 来检查单词是不是下位词,您可以也查找指定单词的所有下位词。有两个方法提供这项服务:
getHyponym() 用来获得下位词
isHyponym() 用来判断两个单词是否下位词
整体名词
整体名词(Holonyms)表示整体,指定单词是它的组成部分。例如“hat”是“brim”和“crown”的整体名词。有两个方法提供这项服务:
getHolonym() 用来取得整体名词
isHolonym() 用来判断两个单词是否整体名词
部分名词
部分名词(Meronyms)表示指定单词的一部分。例如,“brim”和“crown”就是“hat”的部分名词。有两个方法提供这项服务:
getMeronym() 用来取得部分名词
ismeronym() 用来判断两个单词是否部分名词
使用拼写检查器
您可以用 SpellChecker 来捕获拼写错误的单词。对于编辑器、IDE 和其他字处理应用程序来说,它是一个很有用的工具。
您可以从驱动程序得到服务实例来访问SpellChecker,如下所示。文本和 XML 驱动程序都支持这项服务:
SpellChecker spellchecker=driver.getSpellChecker("english");
JADT 的 SpellChecker 提供了以下特性:
查找单词是否正确:调用 SpellChecker 的 check()方法,该方法用单词为参数,返回布尔值:
System.out.println("Word dictionar is right Spelling "+spellchecker.check
(new TextWord("dictionar")));
查找单词的正确形式:调用 SpellChecker 的 correct() 方法,该方法用单词作为参数,返回 DictionaryRecord:
DictionaryRecord dr=spellchecker.correct(new TextWord("dictionar"));
if(dr!=null)
System.out.println("Correct spelling of dictionar is "+dr);
查找类似单词:调用 SpellChecker 的 suggestSimilar() 方法,该方法用单词作为参数,返回 DictionaryRecord:
DictionaryRecord dr=spellchecker. suggestSimilar(new TextWord("dictionar"));
System.out.println("Words similar to dictionar are : ");
dr.Start();
while(dr.hasMoreWords())
System.out.println(dr.getNext());
使用单词表
WordLister 允许您从后端资源取得单词。JADT 的 WordLister 还提供了一个选项,可以查找符合某个规则的所有单词。
可以用以下语句从驱动程序访问这项服务:
WordLister wordlister=driver.getWordlister("english");
目前,它支持用以下方式查找单词:
相似前缀:返回用相同前缀开始的单词:
WordList dr= wordlister.findWithPrefix("perf");
System.out.println("Words with prefix \"perf\" are : ");
if(dr==null)return;
dr.Start();
while(dr.hasMoreWords())
{
System.out.println(dr.getNext());
}
相似后缀:返回用相同单词后缀结束的单词:
WordList dr= wordlister.findWithSuffix("ces");
System.out.println("Words with suffix \"ces\" are : ");
if(dr==null)return;
dr.Start();
while(dr.hasMoreWords())
{
System.out.println(dr.getNext());
}
共享某些子串:返回包含相同单词的单词:
WordList dr= wordlister.findWithSubstring("tiona");
System.out.println("Words with substring \"ces\" are : ");
if(dr==null)return;
dr.Start();
while(dr.hasMoreWords())
{
System.out.println(dr.getNext());
}
使用词变位器
变位词是通过重新排列单词或短语的字母而得到的单词或短语。Anagrammizer 用来取得用相同字符组成的单词,对于文字游戏类应用程序来说会非常有用。使用 Anagrammizer,您可以判断各个单词相互之间是不是变位词,或者找到指定单词的所有变位词。
可以用以下语句从驱动程序访问这项服务:
Anagrammizer anagram=driver.getAnagrammizer("english");
有两个方法提供这项服务:
Anagrammise()用来取得变位词
isAnagram()用来判断两个单词是否变位词
这些方法可以像清单 6 所示的那样使用:
清单 6. Anagrammizer 用法
DictionaryRecord dr= this.wordbook.Anagrammise(new TextWord("clear"));
while(dr!=null)
{
String strName=dr.getWordName();
dr=dr.getNextRecord();
}
if(wordbook. isAnagram("clear","clare"))
{
/*..*/
}
使用语法检查器
GrammarChecker 检查单词在句子中的排列是否允许,检查单词在特定上下文中的用法是否正确。同样,这项服务可以用在出版和字处理应用程序中。
可以用以下语句从驱动程序访问这项服务:
GrammarChecker grammarchecker=yourdriver.getGrammarChecker("english");
使用 JADT 的GrammarChecker,您可以:
用 check() 方法判断是否使用了正确的语法
用 correct() 方法纠正语法
用 suggestSimilar() 方法对如何在具体上下文环境下纠正语法提出建议
使用翻译器
Translator被用来把单词或句子从一种语言转换成另一种语言。这个特性可以用在本地化和国际化实现中。利用这个特性,用一种语言编写的资源绑定文件可以被转换成另外一种语言。
可以用以下代码从驱动程序访问这项服务:
Translator translator=yourdriver.getTranslator("english","french");
使用 JADT 的Translator,您可以:
用 translate() 方法把单词翻译成第二种语言。
用 translateSentence() 方法把句子翻译成第二种语言。
JADT 应用程序示例
JADT 还带有一个示例应用程序,演示了 JADTTextDriver 和 JADTXMLDriver 驱动程序的特性。
要执行示例应用程序,请调用 java com.ibm.jadtsample.JADTSampleApplication 来打开应用程序,运行的效果如图 1 所示:
图 1. 示例应用程序屏幕
确保您是在资源文件部署的目录中执行 java com.ibm.jadtsample.JADTSampleApplication 命令。
结束语
读完这篇文章之后,对于 Java 字典和辞典 API 的工作方式,您应该从用户的角度有了良好的认识。具体来说,您学习了基本的 JADT 结构,学习了如何利用不同的 JADT 服务和组件,用字典和其他与单词有关的特性来建立 Java 应用程序。
在本系列文章的第 2 部分中,我将从字典提供者的角度来考察 JADT,展示他们如何才能为字典和单词数据实现 JADT。
参考资料
您可以参阅本文在 developerWorks 全球站点上的 英文原文。
Download the Dictionary and Thesaurus API for Java from alphaWorks.
Don't miss Part 2 of this series (developerWorks, September 2004), which looks at word references in detail.
从 alphaWorks 下载 IBM XML4J 。
在 developerWorks Java 技术专区上可以找到更多 Java 技术资源。
请访问Developer Bookstore,获得技术书籍的完整列表,其中包括数百本 Java 相关主题的图书。
是否对无需通常的高成本入口点(entry point)或短期评估许可证的 IBM 测试产品感兴趣?developerWorks 工具包订阅 为 WebSphere、DB2、Lotus、Rational 和 Tivoli 产品提供了低成本的 12 个月单用户许可证,包括基于 Eclipse 的 WebSphere Studio IDE,用于开发、测试、评估和展示您的应用程序。
关于作者
Rakesh Midha 是 Bangalore 的 IBM 软件试验室的软件工程师。他目前从事 IBM WebSphere 业务组件开发工作。他有 5 年在多平台和各种关系数据库系统(像 DB2 UDB、Oracle、MySQL 和 Microsoft SQL Server)上进行 Java 和 C++ 服务器端编程的经验。他的专长领域包括在银行、金融、编目行业以及订单和仓储管理系统等领域设计和开发独立的和 n 层分布式系统。他从 Chandigarh 的 Punjab 大学获得了电子工程学士学位,是 Java 字典和辞典方面的技术专家,这项技术是由 IBM alphaWorks 启动