Статьи

Голосова підтримка в XML: Частина 1. Розробляємо програму прослуховування RSS-каналів

  1. Серія контенту:
  2. Цей контент є частиною серії: Голосова підтримка в XML
  3. Про цю серії
  4. основи VoiceXML
  5. Лістинг 1. Базовий формат файлів VXML
  6. Лістинг 2. Приклад файлу VXML
  7. Формат файлів RSS
  8. Лістинг 3. Приклад структури RSS
  9. Лістинг 4. Елемент RSS-стрічки в XML
  10. Застосування простого XSL-перетворення
  11. Лістинг 5. Таблиця стилів XSL для перетворення RSS в VXML
  12. Лістинг 6. Створення файлу VXML за допомогою таблиці стилів XSL
  13. Процес перетворення RSS в VoiceXML
  14. Малюнок 1. Логіка роботи програми для перетворення RSS в VXML
  15. Перетворення RSS в VoiceXML за допомогою Perl
  16. Лістинг 7. Приклад створення файлу VXML з RSS-стрічки за допомогою Perl
  17. Лістинг 8. Приклад VXML-файлу, згенерованого автоматично з RSS-стрічки
  18. Додавання можливості вибору новин
  19. Лістинг 9. Повний текст скрипта на Perl
  20. Лістинг 10. Реалізація функції вибору новин за допомогою VXML
  21. Лістинг 11. Запит на вибір наступної новини
  22. Створення VoiceXML з RSS-стрічок за допомогою сервлетів Java
  23. Лістинг 12. Формування HTTP-заголовка в Perl-скрипт
  24. Лістинг 13. Створення голосових RSS-стрічок c допомогою VXML і JSP
  25. Динамічна генерація різних VXML-файлів
  26. Лістинг 14. CGI-скрипт
  27. Висновок
  28. Ресурси для скачування

Голосова підтримка в XML

Озвучуємо RSS-стрічки і перетворюємо тематичні запити в голосові інструкції, представлені в VoiceXML

Серія контенту:

Цей контент є частиною # з серії # статей: Голосова підтримка в XML

https://www.ibm.com/developerworks/ru/views/global/libraryview.jsp?series_title_by=Голосовая+поддержка+в+xml

Слідкуйте за виходом нових статей цієї серії.

Цей контент є частиною серії: Голосова підтримка в XML

Слідкуйте за виходом нових статей цієї серії.

Цю статтю буде корисно прочитати всім, хто цікавиться перевагами використання голосових програм для читання RSS-стрічок. До того ж ви познайомитеся з основами VoiceXML і форматом RSS XML. Але головне, ви навчитеся:

  • Трансформувати RSS в VXML, використовуючи XSLT
  • Писати скрипти на Perl для генерації VXML
  • Додавати підтримку інтерактивності у ваші файли VXML
  • Генерувати файли VXML, використовуючи сервлети Java ™

Про цю серії

Аудіо та, зокрема, голосові сервіси стають все більш популярні в Інтернет. Як приклади можуть служити всілякі музичні ресурси, а також Web-трансляції, доступні в онлайн. Статті нашої серії розповідають про способи поєднання голосових технологій і XML при розробці таких програм, як:

  • У першій частині: RSS-reader з голосовою підтримкою
  • під другій частині : Календаря з голосовою підтримкою
  • В третій частині : Голосовий програми для роботи з блогами і Twitter
  • В четвертої частини : Програми для голосового пошуку в Yahoo

основи VoiceXML

VoiceXML - це загальна назва для голосових даних XML, в той час як сам файловий формат називається VXML.

VXML особливо корисний при використанні спільно з браузером VoiceXML, що перетворює вміст файлу в мова (так зване Text-To-Speech або TTS-перетворення), а також здатним сприймати голосові команди (тобто мають функцію розпізнавання голосу).

У лістингу 1 показаний базовий формат файлу VXML.

Лістинг 1. Базовий формат файлів VXML
<? Xml version = "1.0&quot;?> <Vxml xmlns = "http://www.w3.org/2001/vxml" version = "2.0"> ... </ vxml>

Далі можна додавати елементи, надавати можливість вибору інформації і розбивати її на блоки. Дані для TTS розміщуються всередині тега <prompt>. У лістингу 2 показано, як можна описати просте речення на VXML для подальшого вимови.

Лістинг 2. Приклад файлу VXML
<? Xml version = "1.0" encoding = "UTF-8&quot;?> <Vxml version = "2.1"> <form> <block> <prompt> I could ask you anything! </ Prompt> </ block> </ form> </ vxml>

Якщо у відповідь на голосові запити очікується будь-яку дію користувача, то в елементах <prompt> можна або перерахувати список відповідей, коректно сприймаються системою розпізнавання мови, або ж запросити введення з телефонної клавіатури. Отримана інформація потім зберігається в змінних, так що можна використовувати звичайні умовні оператори (if / else) для формування відповідей.

Всі ці методи будуть продемонстровані як в даній статті, так і в наступних статтях серії.

Для запуску прикладів до статті вам знадобиться доступ до хостингу для розміщення файлів VXML, а також браузер VoiceXML з функціями TTS і розпізнавання мови. Як правило, подібні компоненти доступні через різного роду телефонні лінії. Наприклад, Voxeo надає голосовий браузер, а також всі необхідні сервіси, зокрема, можливість телефонувати до ваших додатків зі стаціонарних телефонів, використовуючи спеціальний пін-код. Це здійснюється через спеціальний VoIP-сервіс на основі протоколу SIP (Session Initiation Protocol) або ж просто через Skype. Зверніться до розділу ресурси за додатковою інформацією.

Формат файлів RSS

RSS (Really Simple Syndication) - це заснована на XML технологія, призначена для публікації інформації, часто використовуваної в блогах і подібних сайтах. Формат RSS дозволяє легко створювати списки статей або інших інформаційних блоків. Інформацію, що надходить по декількох каналах RSS можна агрегувати, в результаті виходить відформатований список статей, історій і т.д. разом з заголовком і відповідним URL, коротким змістом, а також класифікаторами для кожної із складових частин. Крім цього RSS-стрічка містить інформацію для класифікування всього каналу як єдиного цілого.

RSS - це всього лише один з багатьох XML-форматів для об'єднання даних з різних джерел. Незважаючи на те, що базова структура файлу RSS досить проста, вона може сприйматися на перший погляд важко, тому в лістингу 3 представлений дещо спрощений варіант.

Лістинг 3. Приклад структури RSS
<? Xml version = "1.0" encoding = "UTF-8&quot;?> <! - generator = "wordpress / 2.0.4" -> <rss version = "2.0" xmlns: content = "http: // purl .org / rss / 1.0 / modules / content / "xmlns: wfw =" http://wellformedweb.org/CommentAPI/ "xmlns: dc =" http://purl.org/dc/elements/1.1/ "> < channel> <title> MCslp </ title> <link> http://mcslp.com </ link> <description> News from the desk of Martin MC Brown </ description> <pubDate> Thu, 19 Apr 2007 8:14 : 30 +0000 </ pubDate> <generator> http://wordpress.org/?v=2.0.4 </ generator> <language> en </ language> <item> <title> IBM developerWorks Podcast Interview </ title > ... </ item> <item> <title> ... </ title> ... </ item> </ channel> </ rss>

Заголовна секція містить загальну інформацію про стрічку, як, наприклад, назва блогу (MCslp) або ж загальний опис матеріалу ( "Новини з контори Мартіна Брауна").

також в лістингу 3 представлена ​​додаткова інформація про стрічку, така як дата публікації, що відповідає даті генерації в разі динамічних RSS-каналів. Крім цього присутній окремий блок, що описує кожну статтю в стрічці.

У подібних блоках міститься заголовок статті, коротка резюмуюча інформація, а також більш детальна (або навіть повна) версія матеріалу. Останнє можливе за умови підтримки з боку RSS-каналу. Формат статті представлений в лістингу 4.

Лістинг 4. Елемент RSS-стрічки в XML
<Item> <title> IBM developerWorks Podcast Interview </ title> <link> http://mcslp.com/?p=250 </ link> <comments> http://mcslp.com/?p=250#comments </ comments> <pubDate> Thu, 19 Apr 2007 8:14:28 +0000 </ pubDate> <dc: creator> Martin MC Brown </ dc: creator> <category> Articles </ category> <category> Interviews < / category> <category> IBM developerWorks </ category> <category> Grids </ category> <guid isPermaLink = "false"> http://mcslp.com/?p=250 </ guid> <description> <! [ CDATA [Summary]]> </ description> <content: encoded> <! [CDATA [Full information]]> </ content: encoded> </ item>

Якщо інформація може надаватися в форматі VoiceXML, то деякі з цих елементів можуть ігноруватися. Існують певні обмеження на інформацію, призначену для голосового вимови. Наприклад, назви категорій, глобальні ідентифікатори guid і тому подібні елементи вимовляти не має сенсу.

Основний інтерес представляють такі складові стрічки, як заголовок всього каналу, а також назву і опис для кожної зі статей.

Розглянемо дуже простий спосіб перетворення файлу RSS в VoiceXML.

Застосування простого XSL-перетворення

Один з найпростіших способів перетворення XML-файла RSS у формат VXML полягає в використанні шаблону XSL. Правда, в деяких випадках це може виявитися непростим заняттям, особливо з-за обмежених і кілька заплутаних методів для вибірки елементів і логічного розгалуження в XSL. Але в цілому це непоганий варіант для швидкого вирішення проблеми.

У лістингу 5 показана проста таблиця стилів XSL, що перетворює елементи title і description вихідного файлу RSS в формат VXML. В результаті заголовки і вміст кожної з статей RSS-стрічки можуть бути озвучені.

Лістинг 5. Таблиця стилів XSL для перетворення RSS в VXML
<? Xml version = "1.0" encoding = "UTF-8&quot;?> <Xsl: stylesheet version = "1.0" xmlns: xsl = "http://www.w3.org/1999/XSL/Transform"> <xsl : output method = "xml" omit-xml-declaration = "no" /> <xsl: template match = "/"> <vxml version = "2.0" xmlns = "http://www.w3.org/2001/ vxml "> <form id =" news "> <xsl: for-each select =" rss / channel / item "> <block> <prompt> <xsl: value-of select =" title "/> <break size = "small" /> <xsl: value-of select = "description" /> <break size = "medium" /> </ prompt> </ block> </ xsl: for-each> </ form> </ vxml > </ xsl: template> </ xsl: stylesheet>

Шаблон XSL обробляє всі статті в RSS-стрічці, використовуючи для їх вибірки вираження XPath. Потім значення елементів title і description (заголовка і вмісту відповідно) поміщаються в блоки prompt, що розділяються блоками break. Останні використовуються в VoiceXML для вставки пауз в висновок TTS.

Застосувати XSL-перетворення до XML-документу RSS можна за допомогою утиліти xsltproc. Результат перетворення новинної стрічки BBC показаний в лістингу 6.

Лістинг 6. Створення файлу VXML за допомогою таблиці стилів XSL
$ Xsltproc rsstovxml.xsl rss.xml <? Xml version = "1.0&quot;?> <Vxml xmlns = "http://www.w3.org/2001/vxml" version = "2.0"> <form id = "news" > <block> <prompt> Prince Harry not to serve in Iraq <break size = "small" /> Prince Harry will not be deployed in Iraq because of the security threat, the head of the Army says. <Break size = "medium" /> </ prompt> </ block> ... </ form> </ vxml>

Як видно з лістингу, кожній статті RSS-стрічки відповідає окремий блок з заголовком, паузою і коротким змістом. Далі згенерований VXML-документ можна завантажити в голосовий браузер і прослухати. Але сам по собі цей результат не особливо застосуємо на практиці, тому що крім цього необхідно автоматично завантажувати і перетворювати вміст RSS-стрічки. Іншими словами, треба подумати, як динамічно надавати всю необхідну інформацію в VoiceXML.

Процес перетворення RSS в VoiceXML

Одна з проблем при використанні XSL - це простота і, як наслідок, обмеженість цього підходу, причому як в сенсі способів створення файлу VXML, так і в сенсі його вмісту. Для вирішення цієї проблеми можна використовувати мови програмування, наприклад, Java або Python, що дозволяють виконувати більш складні перетворення.

Перш ніж почати, уявімо собі логіку роботи простого RSS-браузера, як показано на малюнку 1.

Малюнок 1. Логіка роботи програми для перетворення RSS в VXML

Принцип роботи наступний: після отримання вхідного дзвінка, що дзвонить надається вибір з доступних RSS-каналів. Як тільки він вибрав канал, його вміст обробляється і створюється список заголовків всіх статей в стрічці. Таким чином абонент може вибрати і прослухати цікаві для його статті.

Спочатку відбувається обробка RSS-стрічки і формування файлу VXML для прочитання вголос статей і створення основного набору інформації для озвучування.

Перетворення RSS в VoiceXML за допомогою Perl

Існує безліч Perl-модулів для обробки новинних стрічок, найбільш зручним з яких є XML :: FeedPP. Модуль може обробляти будь-яку новинну стрічку, включаючи такі формати, як RSS, RDF і Atom. Крім цього модуль надає доступ до вмісту стрічки через спрощений інтерфейс.

Для розбору вмісту необхідно створити об'єкт типу XML :: FeedPP і передати йому URL стрічки: my $ feed = XML :: FeedPP-> new ($ feedurl) ;.

Решта інформації про стрічку, включаючи заголовок, може бути отримана через цей об'єкт верхнього рівня. Наприклад, заголовок отримують у такий спосіб: $ feed-> title () ;.

Доступ безпосередньо до статей стрічки здійснюється в два етапи: спочатку необхідно отримати список статей за допомогою методу get_item (), а потім звертатися до їх вмісту, викликаючи методи title (), description () і т.д.

У лістингу 7 показано, як можна скласти список новин для даної стрічки.

Лістинг 7. Приклад створення файлу VXML з RSS-стрічки за допомогою Perl
use XML :: FeedPP; my $ feedurl = 'http://newsrss.bbc.co.uk/rss/newsonline_uk_edition/uk/rss.xml'; my $ feed = XML :: FeedPP-> new ($ feedurl); my ($ selection) = ( ''); $ Selection = '<form> <block>'; $ Selection. = '<Prompt>'. $ Feed-> title (). '<Break size = "small" /> </ prompt>'; foreach my $ i ($ feed-> get_item ()) {next unless defined ($ i); next unless ($ i-> link () = ~ m / http /); $ Selection. = Sprintf ( '<prompt>% s. <Break size = "small" /> </ prompt>', $ i-> title ()); } $ Selection. = '&lt;/ Block> </ form>'; print << EOF; <? Xml version = "1.0" encoding = "UTF-8&quot;?> <! DOCTYPE vxml PUBLIC "- // W3C // DTD VOICEXML 2.1 // EN" "http://www.w3.org/TR/voicexml21 /vxml.dtd "> <vxml version =" 2.1 "xmlns =" ​​http: // www / w3 / org / 2001 / vxml "xml: lang =" en-US "> $ selection </ vxml> EOF

скрипт в лістингу 7 складається з двох основних частин. Спочатку скрипт отримує на вхід вміст стрічки і створює блоки prompt на кожен новинний заголовок, зберігаючи висновок в строкової змінної. Потім сформована рядок цілком записується в файл VXML.

Скрипт перебирає всі новини в стрічці і додає у вихідний файл заголовки, розділені короткими паузами. Звичайно для цього завдання можна було використовувати повнофункціональний генератор XML, але оскільки файл має досить просту структуру, то досить простих операторів виведення для додавання в нього інформації.

Відзначте, що на даному етапі RSS-стрічка створена вручну, а результати перетворення видаються в стандартний потік виведення. Таким чином, якщо потрібно створити вихідний файл, то в нього треба просто перенаправити стандартний висновок. Отриманий файл VXML представлений в лістингу 8 (файл скорочений в інтересах економії місця).

Лістинг 8. Приклад VXML-файлу, згенерованого автоматично з RSS-стрічки
<Vxml version = "2.1" xmlns = "http: // www / w3 / org / 2001 / vxml" xml: lang = "en-US"> <form> <block> <prompt> BBC News | UK | UK Edition <break size = "small" /> </ prompt> <prompt> Prince Harry not to serve in Iraq. <Break size = "small" /> </ prompt> <prompt> Madeleine fighting fund launched. <Break size = "small" /> </ prompt> ... </ block> </ form> </ vxml>

Якщо завантажити цей файл у відповідний сервіс VoiceXML і зателефонувати, то у відповідь можна почути список новин, отриманих безпосередньо зі стрічки RSS.

Поки що можна лише прослухати список заголовків новин. Звичайно, було б бажано крім заголовків мати можливість послухати і подробиці обраних новин.

Додавання можливості вибору новин

Щоб додати можливості вибору новин і прослуховування їх коротких версій (summary), необхідно передбачити кілька додаткових дій на етапі створення файлу VXML, а саме:

  1. Створити пронумерований список для вибору новин і передбачити можливість вибору елементів зі списку.
  2. Реалізувати можливість обробки вхідного параметра, що представляє собою номер новини для прослуховування. Параметр може бути в голосовому вигляді, але в даному випадку ми будемо використовувати формат DTMF.
  3. Помістити короткі версії новин в файл VXML.

Реалізувати перша дія досить просто: все що потрібно - це привласнити унікальний номер кожної новини і виводити його поруч із заголовком. Крім цього, необхідно, щоб пронумеровані заголовки точно відповідали змісту новин, що видаються за запитом користувача. Для цього будуть використовуватися дві тимчасових строкових змінних: одна буде зберігати номер обраної новини, а інша - текст, який буде озвучений для користувача.

Для отримання і обробки введення з клавіатури можна використовувати спеціальний елемент field, передбачений в VXML: <field name = "select_num" type = "digits">.

В цьому випадку система буде очікувати числового введення від користувача. Після цього відбудеться розбір числового блоку в VXML, і отримане число буде використано для вибору потрібної новини. Потім короткий зміст новини буде сказано вголос голосовим сервісом.

Розбір числового значення відбувається наступним чином: всі цифри числа послідовно вводяться в вигляді сигналів DTMF (Dual Tone Multi-Frequency), а потім поміщаються в спеціальну змінну: <assign name = "selection" expr = "select_num" />.

Таким чином, можна отримувати і обробляти багатозначні числа, хоча в нашому прикладі користувач зможе вибирати тільки з шести останніх новин.

Як тільки цифри введені, можна використовувати звичайний блок умовного переходу (if) для вибору новини для прослуховування.

Повний варіант скрипта (знову на Perl) показаний в лістингу 9.

Лістинг 9. Повний текст скрипта на Perl
use XML :: FeedPP; my $ feedurl = 'http://newsrss.bbc.co.uk/rss/newsonline_uk_edition/uk/rss.xml'; my $ feed = XML :: FeedPP-> new ($ feedurl); my ($ selection, $ detail, $ counter) = ( '', '', 0); $ Selection = '<form id = "MainMenu"> <field name = "select_num" type = "digits">'; $ Selection. = '<Prompt>'. $ Feed-> title (). '<Break size = "small" /> </ prompt>'; $ Selection. = '<Prompt> Please select a story from the following list. </ Prompt>'; foreach my $ i ($ feed-> get_item ()) {next unless defined ($ i); next unless ($ i-> link () = ~ m / http /); # Виведемо тільки 6 останній новин last if ($ counter ++> = 6); if ($ counter == 1) {$ detail. = '<filled> <assign name = "selection" expr = "select_num" />'; $ Detail. = "<If cond = \" selection == '$ counter' \ ">"; } Else {$ detail. = "<Elseif cond = \" selection == '$ counter' \ "/>"; } $ Detail. = Sprintf ( '<prompt>% s.% S <break size = "small" /> <reprompt /> </ prompt>', $ i-> title (), $ i-> description () ); $ Selection. = Sprintf ( '<prompt>% d:% s <break size = "small" /> </ prompt>', $ counter, $ i-> title ()); } $ Selection. = '<Noinput> Please select a number. <Reprompt /> </ noinput> '; $ Selection. = '<Nomatch> Please select a valid number. <Reprompt /> </ nomatch> '; $ Selection. = '</ Field>'; $ Detail. = '</ If> <clear namelist = "select_num" /> <reprompt /> </ filled> </ form>'; print << EOF; <Vxml version = "2.1"> $ selection $ detail </ vxml> EOF

Згенерований файл VXML представлений в лістингу 10. Крім самих новин, в файлі показано, як обробляється вхідний параметр для вибору зі списку, а також як видаються підказки користувачеві, що полегшують роботу з системою.

Лістинг 10. Реалізація функції вибору новин за допомогою VXML
<Vxml version = "2.1"> <form id = "MainMenu"> <field name = "select_num" type = "digits"> <prompt> BBC News | UK | UK Edition <break size = "small" /> </ prompt> <prompt> Please select a story from the following list. </ Prompt> <prompt> 1: Prince Harry not to serve in Iraq <break size = "small" /> </ prompt> <prompt> 2: Madeleine fighting fund launched <break size = "small" /> </ prompt > <prompt> 3: Salmond elected as first minister <break size = "small" /> </ prompt> <prompt> 4: Sainsbury profits jump to £ 380m <break size = "small" /> </ prompt> <prompt > 5: Police boo John Reid over pay <break size = "small" /> </ prompt> <prompt> 6: Uncle jailed for owning death dog <break size = "small" /> </ prompt> <noinput> Please select a number. <Reprompt /> </ noinput> <nomatch> Please select a valid number. <Reprompt /> </ nomatch> </ field> <filled> <assign name = "selection" expr = "select_num" /> <if cond = "selection == '1'"> <prompt> Prince Harry not to serve in Iraq. Prince Harry will not be deployed in Iraq because of the security threat, the head of the Army says. <Break size = "small" /> </ prompt> <elseif cond = "selection == '2'" /> <prompt> Madeleine fighting fund launched. A fighting fund is launched to help cover escalating costs in the search for missing Madeleine McCann. <Break size = "small" /> </ prompt> <elseif cond = "selection == '3'" /> <prompt> Salmond elected as first minister. Alex Salmond makes history after becoming the first Nationalist to be elected first minister of Scotland. <Break size = "small" /> </ prompt> <elseif cond = "selection == '4'" /> <prompt> Sainsbury profits jump to £ 380m. Sainsbury's, the supermarket chain that was the target of takeover speculation, sees its full-year profits surge. <Break size = "small" /> </ prompt> <elseif cond = "selection == '5'" /> <prompt> Police boo John Reid over pay. Home Secretary John Reid is booed over pay proposals at the Police Federation's annual conference. <Break size = "small" /> </ prompt> <elseif cond = "selection == '6'" /> <prompt> Uncle jailed for owning death dog. The uncle of a five-year-old girl killed by a pit bull terrier is jailed for eight weeks for owning an illegal dog. <Break size = "small" /> </ prompt> </ if> <clear namelist = "select_num" /> <reprompt /> </ filled> </ form> </ vxml>

Завантаживши цей файл в VoiceXML-браузер, ви зможете не тільки слухати заголовки новин, а й вибрати ту, яку ви хочете прослухати більш докладно. Крім цього, після прослуховування існує можливість вибору іншої новини. За це відповідає останній блок у файлі (див. Лістинг 11).

Лістинг 11. Запит на вибір наступної новини
<Clear namelist = "select_num" /> <reprompt />

Необхідно очищати змінну, що зберігає попереднє значення призначеного для користувача введення, інакше наступний вибір буде некоректним.

Незважаючи на те, що RSS-стрічка завантажується динамічно, скрипт як і раніше генерує статичний файл VXML, що містить новини для прослуховування. Для повної інтерактивності необхідно створювати його на льоту.

Створення VoiceXML з RSS-стрічок за допомогою сервлетів Java

До цього моменту вона дуже обмежена новин були обмежені статичним файлом VXML. Для справжньої інтерактивності, він повинен генеруватися скриптом динамічно за запитом користувача. Оскількі більшість голосових браузерів звертаються до VXML-файлів по URL, все що потрібно - це розробити CGI або будь-яке ще Web-додаток для їх створення на льоту.

Це можна реалізувати за допомогою Perl-скриптів, представлених на лістингах 7 и 9 , Але необхідно подбати про формування коректного заголовка HTTP-відповіді (text / xml) перед виведенням самого файлу VXML. Все що потрібно - це додати два рядки в початок скрипта, як показано в лістингу 12.

Лістинг 12. Формування HTTP-заголовка в Perl-скрипт
use CGI qw /: standard /; print header (-type => 'text / xml');

За допомогою цих інструкцій імпортується спеціальна бібліотека CGI, що відповідає за формування заголовків HTTP. А решта вміст виведення - це все той же файл VXML, що і раніше.

На основі тих же принципів можна створювати VXML і на інших мовах програмування. Зокрема, в лістингу 13 показаний Java-сервлет, що генерує такий же документ VXML, як і перший Perl-скрипт (див. лістинг 7 ). Сервлет використовує бібліотеки Rome і JDOM для розбору RSS-стрічки і створення необхідного VXML-файлу.

Лістинг 13. Створення голосових RSS-стрічок c допомогою VXML і JSP
import java.net.URL; import java.util.Iterator; import java.io.BufferedInputStream; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.PrintWriter; import java.util.Calendar; import javax.servlet. *; import javax.servlet.http. *; import com.sun.syndication.feed.module.Module; import com.sun.syndication.feed.synd.SyndEntry; import com.sun.syndication.feed.synd.SyndFeed; import com.sun.syndication.io.SyndFeedInput; import com.sun.syndication.io.XmlReader; public class VXMLRSS extends HttpServlet {public void doGet (HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {BufferedInputStream bis = null; PrintWriter out = null; try {out = res.getWriter (); res.setContentType ( "text / xml"); printHeader (out); printNews (out); printFooter (out); } Finally {if (out! = Null) out.close (); if (bis! = null) bis.close (); }} Public void doPost (HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {doGet (req, res); } Private void printHeader (PrintWriter out) throws IOException {out.println ( &quot;<? Xml version = \" 1.0 \ "encoding = \" UTF-8 \ &quot;?>"); out.println ( "<vxml version = \" 2.1 \ ">"); } Private void printNews (PrintWriter out) throws IOException {try {final URL feedUrl = new URL ( "http://newsrss.bbc.co.uk/rss/newsonline_uk_edition/uk/rss.xml"); final SyndFeedInput input = new SyndFeedInput (); final SyndFeed feed = input.build (new XmlReader (feedUrl)); out.println ( "<form> <block>" + "<prompt>" + feed.getTitle () + "<break size = \" small \ "/> </ prompt>"); for (final Iterator iter = feed.getEntries (). iterator (); iter.hasNext ();) {out.println ( "<prompt>" + ((SyndEntry) iter.next ()). getTitle () + " <break size = \ "small \" /> </ prompt> "); } Out.println ( "</ block> </ form>"); } Catch (Exception ex) {ex.printStackTrace (); System.out.println ( "ERROR:" + ex.getMessage ()); }} Private void printFooter (PrintWriter out) throws IOException {out.println ( "</ vxml>"); }}

Основні кроки по розбору стрічки і генерації VXML залишилися точно такими ж, як і в разі скриптів Perl. Замість використання одного статичного VXML-файлу, відбувається звернення до RSS-стрічки і створення VXML при запиті користувача.

Далі цей сервлет разом з необхідними JAR-файлами для JDOM і Rome, можна розгорнути в контейнері JSP, наприклад в Apache Tomcat, і використовувати його як основу вашого майбутнього VXML-додатки.

Динамічна генерація різних VXML-файлів

Крім озвучування будь-якої конкретної RSS-стрічки, можна надавати користувачеві список новинних каналів для прослуховування. Це також дає можливість додати інтерактивності з додатком, а саме, вибирати, який скрипт і звідки викликати при виборі тієї чи іншої новини користувачем.

Для початку треба створити список RSS-стрічок, доступних для озвучування. У нашому прикладі використовується звичайний масив, але в принципі ця інформація може завантажуватися з якоїсь бази даних. Далі для кожної стрічки витягується її назву і опис, створюється необхідний пронумерований список, після чого скрипт чекає вибору користувача. Однак в цьому випадку, після отримання від користувача конкретного числа, скрипт викликає зовнішній обробник по URL (в даному випадку, самого себе), передаючи номер новинної стрічки в якості аргументу. На кінцевому етапі можна викликати додаткову функцію, яка видає список новин конкретної стрічки і дозволяє вибрати одну з них.

У лістингу 14 представлений повний код CGI-скрипта на Perl, що виконує перераховані вище дії.

Лістинг 14. CGI-скрипт
#! / Usr / bin / perl use XML :: FeedPP; use CGI qw /: standard /; print header (-type => 'text / xml'); my ($ feeds) = [ 'http://newsrss.bbc.co.uk/rss/newsonline_uk_edition/uk/rss.xml', 'http://mcslp.com/wp-rss2.php']; if (param ( 'selection') = ~ m / [0-9] + /) {output_news_feed ($ feeds -> [param ( 'selection')]); } Else {output_feed_list (); } Sub output_feed_list {my ($ selection, $ detail, $ counter) = ( '', '', 0); $ Selection = '<form id = "MainMenu"> <field name = "select_num" type = "digits">'; $ Selection. = '<Prompt> MCSLP News Feed Reader <break size = "small" /> </ prompt>'; $ Selection. = '<Prompt> Please select a news source from the following list. </ Prompt>'; foreach my $ feedurl (@ {$ feeds}) {my $ feed = XML :: FeedPP-> new ($ feedurl); $ Counter ++; if ($ counter == 1) {$ detail. = '<filled> <assign name = "selection" expr = "select_num" />'; $ Detail. = "<If cond = \" selection == '$ counter' \ ">"; } Else {$ detail. = "<Elseif cond = \" selection == '$ counter' \ "/>"; } $ Detail. = Sprintf ( '<goto next = "http://www.mcslp.com/ rsstovxmlopt.cgi? Selection =% s" />', $ counter); $ Selection. = Sprintf ( '<prompt>% d:% s <break size = "small" /> </ prompt>', $ counter, $ feed-> title ()); } $ Selection. = '<Noinput> Please select a number. <Reprompt /> </ noinput> '; $ Selection. = '<Nomatch> Please select a valid number. <Reprompt /> </ nomatch> '; $ Selection. = '</ Field>'; $ Detail. = '</ If> <clear namelist = "select_num" /> <reprompt /> </ filled> </ form>'; print << EOF; <? Xml version = "1.0" encoding = "UTF-8&quot;?> <Vxml version = "2.1"> $ selection $ detail </ vxml> EOF} sub output_news_feed {my ($ feedurl) = @_; my $ feed = XML :: FeedPP-> new ($ feedurl); my ($ selection, $ detail, $ counter) = ( '', '', 0); $ Selection = '<form id = "MainMenu"> <field name = "select_num" type = "digits">'; $ Selection. = '<Prompt>'. $ Feed-> title (). '<Break size = "small" /> </ prompt>'; $ Selection. = '<Prompt> Please select a story from the following list. </ Prompt>'; foreach my $ i ($ feed-> get_item ()) {next unless defined ($ i); next unless ($ i-> link () = ~ m / http /); last if ($ counter ++> = 6); if ($ counter == 1) {$ detail. = '<filled> <assign name = "selection" expr = "select_num" />'; $ Detail. = "<If cond = \" selection == '$ counter' \ ">"; } Else {$ detail. = "<Elseif cond = \" selection == '$ counter' \ "/>"; } $ Detail. = Sprintf ( '<prompt>% s.% S <break size = "small" /> </ prompt>', $ i-> title (), $ i-> description ()); $ Selection. = Sprintf ( '<prompt>% d:% s <break size = "small" /> </ prompt>', $ counter, $ i-> title ()); } $ Selection. = '<Noinput> Please select a number. <Reprompt /> </ noinput> '; $ Selection. = '<Nomatch> Please select a valid number. <Reprompt /> </ nomatch> '; $ Selection. = '</ Field>'; $ Detail. = '</ If> <clear namelist = "select_num" /> <reprompt /> </ filled> </ form>'; print << EOF; <? Xml version = "1.0" encoding = "UTF-8&quot;?> <Vxml version = "2.1"> $ selection $ detail </ vxml> EOF}

У прикладі мається на увазі, що один параметр використовується як для виведення всього списку стрічок, так і для вибору конкретної стрічки зі списку. У разі використання бази даних, швидше за все, буде потрібно присвоювати унікальний ідентифікатор кожної стрічці і використовувати його для вибору. Але загальний принцип залишається незмінним.

До речі кажучи, необхідного результату можна досягти використовуючи тільки VXML. У VXML можна додавати різні блоки form, а потім використовувати їх для виведення потрібних стрічок. Але на практиці створювати VXML-файли великого розміру, як правило, не варто, набагато краще використовувати скрипти для швидкої генерації невеликих обсягів VXML-даних на льоту.

Використовуючи таку динамічну генерацію VXML, слід подбати про те, щоб вона не уповільнює роботу програми. Наприклад, вищенаведений скрипт безпосередньо звертається до кожної новинній стрічці, що може займати значний час. Використовуючи базу даних, можна завантажувати і виводити заголовок і короткий опис стрічок набагато швидше.

Крім цього, майте на увазі, що в разі динамічної генерації можуть знадобитися додаткові зусилля по обробці можливих помилок. Наприклад, в нашому випадку якщо яка-небудь зі стрічок недоступна, то скрипт виведе порожній список новин, в той час як повідомлення типу: "Вибачте, сервіс в даний час недоступний" було б значно інформативніше для користувача при виникненні такої ситуації.

Висновок

У даній статті були розглянуті різні підходи до генерування документів VXML, необхідних для прослуховування RSS-стрічок. Ми почали з простого варіанту на основі XSL, а потім перейшли до більш гнучких рішень, що використовують скрипти Perl і сервлети Java.

Самі по собі скрипти досить примітивні. Вся міць полягає в створеному VXML-вмісті, а також в голосовому браузері, що використовує VXML для надання голосового інтерфейсу. Крім цього, в статті розповідалося як забезпечувати певний рівень інтерактивності, використовуючи VXML спільно з динамічними скриптами. Все це дозволяє відносно легко розробляти досить складні голосові програми.

Залишайтеся з нами, і під другій частині ми розробимо календар з голосовою підтримкою.

Ресурси для скачування

Схожі тими

  • Оригінал статті: Voice enabling XML, Part 1: Develop a voice-enabled RSS-reader (Мартін Браун (Martin Brown), developerWorks, серпень 2007 року). (EN)
  • Навчитеся використовувати Java-сервлети в VoiceXML-додатках, читаючи статтю Створення VoiceXML-сторінок в інтегрованому середовищі Web-розробки на мові Java, частина 1: Генерування VoiceXML з використанням Java-сервлетов і JSP-сторінок (Брет Маклафлін (Brett McLaughlin), developerWorks, січень 2006 р). (EN)
  • Ознайомтеся з тим, як Java-сервлети допомагають створювати більш складні додатки в статті Створення VoiceXML-сторінок в інтегрованому середовищі Web-розробки на мові Java, частина 2: розширення можливостей VoiceXML-додатків на основі Java (Брет Маклафлін (Brett McLaughlin), developerWorks, січень 2006 р). (EN)
  • скачайте Rome RSS / Atom syndication - набір відкритих утиліт і бібліотек на Java, що дозволяють розбирати, генерувати і публікувати стрічки RSS і Atom. (EN)
  • Зверніться до Perl-сховища CPAN за модулем XML :: FeedPP . (EN)
  • скачайте бібліотеку JDOM , Що включає в себе DOM-парсер XML для Java, який необхідний для роботи бібліотеки Rome RSS. (EN)
  • За інформацією про хостинг для додатків VoiceXML зверніться до Інтернет-сервісу Voxeo , Що надає доступ через звичайний VoIP і Skype. (EN)
  • Зверніться до специфікації VoiceXML 2.1 за переліком можливостей, як правило реалізуються на платформах VoiceXML. (EN)
  • Сертифікація по XML корпорації IBM : Дізнайтеся, як стати сертифікованим розробником IBM в області XML і пов'язаних з ним технологій. (EN)
  • Зверніться до розділу XML сайту developerWorks, який містить безліч статей, порад, інструкцій, стандартів, а також IBM Redbooks.
  • скачайте програмне забезпечення IBM (час роботи без реєстрації обмежена) : Почніть ваш наступний проект, використовуючи програмне забезпечення, яке можна завантажити прямо з сайту IBM developerWorks. (EN)

Підпішіть мене на ПОВІДОМЛЕННЯ до коментарів

Jsp?
Quot;?
Org/?
Com/?
Com/?
Com/?
Xml <?
Quot;?
Lt;/ Block> </ form>'; print << EOF; <?
Quot;<?

Новости