Yahoo翻译API的使用

在日语学习中比较困难的部分是记住日本汉字(Kanji)的发音,因为日本汉字不管训读还是音读都和现代汉语相应汉字的发音相差很多。而且日语中大量多音字、多音词组的存在使得对日本汉字的学习异常繁琐。

我一般会将不会读的汉字复制到Google翻译里,因为目前可用的在线翻译引擎中只有Google会提供准确的经过分词的罗马音标注,但是目前Google Translation API已经关闭公开访问了。经过艰难的搜寻,我最后选择了Yahoo日本提供的翻译API作为替代方案。

首先去Yahoo Developer Center注册一个账号,然后使用其提供的ルビ振り这个模块。先解释一下这个ルビ振り:

give [print] kana alongside kanji [Chinese characters] (to show the letters' readings),

这个词读作ルビrubi 振りfuri,有个html元素就叫<ruby>,它提供了一个文字注音的环境,其中<rb>是文字<rt>是其注音,在这个项目中,<ruby>元素起到了非常关键的作用。

账号注册成功得到一个ID,再回到ルビ振り这个页面,使用方法是http://jlp.yahooapis.jp/FuriganaService/V1/furigana?appid=<あなたのアプリケーションID>&sentence=出会え这里只需要填写appidsentence两个选项,那个grade(相应年级的注音完整度)会导致汉字的注音显示不全,所以就不设置了。

网络请求返回一堆xml数据:

<?xml version="1.0" encoding="UTF-8"?>  
<ResultSet xmlns="urn:yahoo:jp:jlp:FuriganaService" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="urn:yahoo:jp:jlp:FuriganaService http://jlp.yahooapis.jp/FuriganaService/V1/furigana.xsd">  
  <Result>
    <WordList>
      <Word>
        <Surface>出会え</Surface>
        <Furigana>であえ</Furigana>
        <Roman>deae</Roman>
        <SubWordList>
          <SubWord>
            <Surface>出会</Surface>
            <Furigana>であ</Furigana>
            <Roman>dea</Roman>
          </SubWord>
          <SubWord>
            <Surface>え</Surface>
            <Furigana>え</Furigana>
            <Roman>e</Roman>
          </SubWord>
        </SubWordList>
      </Word>
    </WordList>
  </Result>
</ResultSet>  

首先,输入的语句被分词了,分出来的词语存放在<Word>里,<Surface>是原文,<Furigana>是假名标注,<Roman>是罗马音标注,值得注意的是,有的词语还会出现<SubWord>,这应该和日语语法有关,我还没弄懂,但是我不需要这个<SubWord>,所以首先要去除它。

关于跨域问题,可以使用jsonp方法,但是Yahoo日本没有给出json格式的返回值,导致js在分析返回的xml数据时会报错,所以jsonp就没办法用了。后来我查到可以使用Yahoo的YQL(此服务已停用,故下文方法失效,但思路类似)服务进行跨域的xml处理:

var sentence = $("#input").val();  
var url = 'http://jlp.yahooapis.jp/FuriganaService/V1/furigana?&appid='+sentence;  
var yql = 'https://query.yahooapis.com/v1/public/yql?q=' + encodeURIComponent('select * from xml where url="' + url + '"') + '&format=xml';

$.ajax({
    url: yql,
    dataType: 'xml',
    success: function(data) {
    },
})

注意这里dataType一定要选xml。随后在callback里我要做下列几件事:

首先,去掉所有的<SubWord>,这里使用remove()方法就可以了:

var deleteSubword = $(data).find('SubWordList').each(function() {  
    $(this).remove();
});

其次,对于输入的标点符号,由于他们没有对应的<Roman>tag,所以注音部分要写入空白元素,如果找到<Roman>,就document.createTextNode(romaji),并用var rt = $("<rt/>");生成一个node,把词组的romaji放进去,同理处理kanji,最后each遍历结束后:

.promise().done(function() {
    $("#output").html(ruby);
});

来更新输出内容。

项目全体代码如下:

var romaji = $(data).find('Word').each(function() {  
var romajinode = document.createTextNode("");  
if ($(this).find('Roman')) {  
    var romaji = $(this).find('Roman').text();
    romajinode = document.createTextNode(romaji);
}
    var kanji = $(this).find('Surface').text();
    var kanjinode = document.createTextNode(kanji);
    var rb = $("<rb/>");
    rb.append(kanjinode);
    ruby.append(rb);
    var rt = $("<rt/>");
    rt.append(romajinode);
    ruby.append(rt);
}).promise().done(function() {
    $("#output").html(ruby);
});

这个API存在的问题是,Yahoo日本作为一个日企对日语的解析居然不如Google,比如私ははい中的全部被标成了ha,另外技术上的问题就是返回数据类型是xml而不是json,处理使用起来不是那么方便。