Главная » XSLT » Генерация Web-сайтов из тематических карт

0

Задача

Требуется получить знания о предмете, представленном в тематической кар­те, и на этой основе сгенерировать с помощью XSLT Web-сайт.

Решение

В основу решения положен каркас Cogitative Topic Maps Web Site (CTW), представленный публике в сборнике статей XML Topic Maps под редакцией Джека Парка (Jack Park) (Addison Wesley, 2002). Оригинальная работа была выполнена в компании Extreme Markup Languages в 2000 году.

В каркасе CTW принято следующее отображение элементов тематических карт на HTML:

Элемент тематической карты HTML-разметка

Тематическая карта       Web-сайт

Тема                                Web-страница

Тематические ассоциации Карта сайта

Вхождения тем              Рисунки, графика, текст, фрагменты HTML и т.д.

Имена тем                      Заголовки страниц, списки и текст гиперссылок.

Предмет нашей тематической карты – алгоритмы, точнее, алгоритмы сорти­ровки. Представленные в карте знания собраны из различных информационных источников в Интернете и организованы в виде ассоциаций типа класс-подкласс между алгоритмами и вхождениями описаний типов, демонстраций и примеров кода на нескольких языках программирования.

Определившись с предметом и содержанием Web-сайта, мы можем естествен­но выстроить онтологию субъектов и объектов. Онтологический уровень в CTW состоит из двух основных частей: классификация предметов темы сайта и класси­фикация характеристик темы, составляющих содержание страниц.

Обе классификации играют важную роль в управлении внешним обликом сайта. Типы тем определяют верстку страницы, а типы характеристик тем – сти­ли отдельных элементов и строительных блоков. Результаты изображены на рис. 13.3.

Рис. 13.3. Внешний вид сгенерированного сайта

В следующих разделах описываются предметы, представленные на сайте «Ал­горитмы сортировки».

Алгоритмы сортировки

Основные предметы нашего сайта – это различные подклассы класса «алго­ритм сортировки».

<topic id="sort">

</topic> <association>

<instanceOf>

<topicRef xlink:href="#_class-subclass"/> </instanceOf> <member>

<roleSpec>

<topicRef xlink:href="#_superclass"/> </roleSpec>

<topicRef xlink:href="#sort"/> </member> <member>

<roleSpec>

<topicRef xlink:href="#_subclass"/> </roleSpec>

<topicRef xlink:href="#simplesort"/> <topicRef xlink:href="#in-place sort"/> <topicRef xlink:href="#heapsort"/> <topicRef xlink:href="#adaptivesort"/> <topicRef xlink:href="#distributionsort"/> <topicRef xlink:href="#mergesort"/> </member> </association>

Полная версия тематической карты и XSLT-сценариев есть на сайте http:// www.cogx.com/ctw. В этом разделе мы приводим только некоторые фраг­менты для иллюстрации различных команд.

У любого алгоритма сортировки могут быть свои подклассы, например, мож­но насчитать четыре разновидности сортировки на месте (in-place-sort), у каждого из которых в свою очередь могут быть подклассы:

<association> <instanceOf>

<topicRef xlink:href="#_class-subclass"/> </instanceOf> <member>

<roleSpec>

<topicRef xlink:href="#_superclass"/> </roleSpec>

<topicRef xlink:href="#in-place sort"/> </member> <member>

<roleSpec>

<topicRef xlink:href="#_subclass"/> </roleSpec>

<topicRef xlink:href="#quicksort"/>

<topicRef xlink:href="#insertionsort"/> <topicRef xlink:href="#selsort"/> <topicRef xlink:href="#dimincrsort"/> </member>

</association>

Национальный институт стандартов и технологий США (National Institute of Standards and Technology (NIST)) поддерживает замечательный сайт, посвящен­ный алгоритмам (http://www.nist.gov/dads/), на котором каждому алгоритму от­ведена отдельная страница. В нашей карте URL этих страниц служат идентифи­каторами предметов:

<topic id="insertionsort"> <subjectIdentity>

<subjectIndicatorRef

xlink:href="http://www.nist.gov/dads/HTML/insertsrt.html"/> </subjectIdentity>

Помимо отношения к другим алгоритмам, которое описывается ассоциация­ми класс-подкласс, у алгоритмов сортировки есть и иные характеристики, напри­мер, базовое имя и вхождения.

В данной тематической карте алгоритмам сортировки присвоены имена, под которыми они широко известны:

<baseName>

<baseNameString>соpтиpовка вставками</baseNameString> </baseName>

Иногда имеются альтернативные имена, представленные как базовые имена в контексте also-known-as:

<baseName> <scope>

<topicRef xlink:href="#also-known-as"/> </scope>

<baseNameString>линейная сортировка вставками </baseNameString> </baseName>

Описание алгоритма представлено в виде вхождения типа description в контексте источника описания. Следующий код содержит цитату с сайта Наци­онального института стандартов и технологий США (по этой причине она приве­дена в контексте темы nist). Прочесть его можно так: «В контексте NIST сорти­ровка вставками описывается как …».

<occurrence> <instanceOf>

<topicRef xlink:href="#description"/> </instanceOf> <scope>

<topicRef xlink:href="#nist"/> </scope>

<resourceData>Выбирается следующий элемент и вставляется в конечную структуру данных в нужное место относительно вставленных ранее элементов. </resourceData> </occurrence>

Ссылки на демонстрации работы алгоритмов, например аплеты и анимации, представлены вхождениями типа demonstration:

<occurrence> <instanceOf>

<topicRef xlink:href="#demo"/> </instanceOf> <resourceRef xlink:href=

"http://www.cosc.canterbury.ac.nz/people/mukundan/dsal/ISort.html"/> </occurrence>

Ссылки на реализации алгоритмов сортировки тоже можно представить в карте в виде вхождений типа code sample, описанных в контексте языка про­граммирования. Языки программирования – это другой класс тем, представлен­ных на сайте, с собственной независимой навигацией.

<occurrence> <instanceOf>

<topicRef xlink:href="#code"/> </instanceOf> <scope>

<topicRef xlink:href="#fortran"/> </scope> <resourceRef

xlink:href="http://gams.nist.gov/serve.cgi/Module/TOMS/5 05/85 47"/> </occurrence> <occurrence> <instanceOf>

<topicRef xlink:href="#code"/> </instanceOf> <scope>

<topicRef xlink:href="#java"/> </scope>

<resourceRef xlink:href=

"http://www.cs.ubc,ca/spider/harrison/Java/InsertionSortAlgorithm.java"/> </occurrence> </topic>

Это вся информация об алгоритмах, которую мы решили включить. Далее мы построим на ее основе заголовки страниц, ссылки на родственные алгоритмы, описания, ссылки на Web-страницы, где можно найти определение алгоритма, ссылки на демонстрацию работы алгоритма и примеры кода со ссылками на язы­ки программирования, на которых эти примеры реализованы.

Языки программирования

Нас интересует лишь тот факт, что языки программирования с точки зре­ния названия и определения являются экземплярами класса programming language:

<topic id="java"> <subjectIdentity>

<subjectIndicatorRef

xlink:href="http://foldoc.doc.ic.ac.uk/foldoc/foldoc.cgi?query=java"/> </subjectIdentity> <instanceOf>

<topicRef xlink:href="#plang"/> </instanceOf> <baseName>

<baseNameString>Java</baseNameString> </baseName> <occurrence> <instanceOf>

<topicRef xlink:href="#definition"/> </instanceOf> <scope>

<topicRef xlink:href="#cnet"/> </scope>

<resourceData>Язык Java был разработан компанией Sun Microsystems для добавления анимации и других действий к Web-сайтам. Небольшие приложения (аплеты), созданные на Java могут выполняться в любой графической системе, имеющей доступ к Web, но для этого необходим браузер с поддержкой Java. Согласно описанию Sun Java — "простой объектно-ориентированный, распределенный, интерпретируемый, надежный, безопасный, архитектурно-независимый, переносимый, высокопроизводительный, многопоточный, динамический, современный, универсальный язык программирования". </resourceData> </occurrence>

</topic>

Показанная на рис. 13.4 страница описания языка программирования содер­жит ссылки на примеры кода, написанного на этом языке, и перекрестные ссылки на реализованные алгоритмы.

Корневая тема

В каркасе CTW root – это тема, для которой индикатором предмета слу­жит сам документ, содержащий тематическую карту. В терминологии тематических

Рис. 13.4. Страница описания языка программирования

карт корневая тема – материализация того документа, которому она принад­лежит:

<topic id="default"> <subjectIdentity>

<subjectIndicatorRef xlink:href="#map"/> </subjectIdentity>

При объединении тематических карт в CTW эта тема добавляется в контек­сты всех характеристик тем. Важнее, впрочем, тот факт, что она соответствует на­чальной странице сайта.

В следующем примере имя корневой темы отображается в виде гиперссылки в левом верхнем углу на любой странице сайта:

<baseName>

<baseNameString>AnropMTMbi copTMpoBKM</baseNameString> </baseName>

Здесь самое место поместить аннотации к тематической карте. Мы ограничи­лись лишь описанием проекта и копирайтом.

<occurrence>

<instanceOf>

<topicRef xlink:href="#definition"/> </instanceOf>

<resourceData><![CDATA[ Этот сайт посвящен алгоритмам, точнее, алгоритмам сортировки. <br><br>

Он создан для рецепта, описывающего каркас CTW в книге XSLT Cookbook издательства O’Reilly.]]> </resourceData> </occurrence> </topic>

На начальной странице (рис. 13.5) сайта показано только описание проекта.

Рис. 13.5. Начальная страница сайта, посвященного алгоритмам сортировки

Элементы и верстка страницы

Сначала определим переменную root, которая будет представлять корневую тему. Как было сказано выше, индикатором этой темы является документ, кото­рый содержит тематическую карту:

<xsl:variable name="root"

select="//topic[subjectIdentity/subjectIndicatorRef/@xlink:href

= concat(‘#’,/topicMap/@id)]"/>

Тот же узел можно было бы найти с помощью ключа subjectlndicator, который ищет темы по адресам индицирующих их ресурсов:

<xsl:key

name = "subjectlndicator" match = "topic"

use = "subjectIdentity/subjectIndicatorRef/@xlink:href" />

<xsl:variable name="root"

select="key(‘subjectIndicator’,concat(,#,,/topicMap/@id))"/>

Первым делом генерируем начальную страницу, вызывая шаблон верстки root-page для корневой темы:

<xsl:template match="/">

<xsl:call-template name="root-page">

<xsl:with-param name="this" select="$root"/> </xsl:call-template>

Затем генерируем страницы для каждого подкласса класса sorting algorithm. Здесь вызывает шаблон верстки algorithm-page, которому в качестве параметра передается строка sorting algorithm. Шаблон рекур­сивно вызывает себя самого для обхода всех подклассов до самого нижнего уровня:

<xsl:call-template name="algorithm-page">

<xsl:with-param name="this" select="key(‘topicByID’,,#sort,)"/> </xsl:call-template>

Таблица стилей генерирует страницы для каждого языка программирования, вызывая шаблон plang-page:

<xsl:for-each select="key(‘instanceOf’,,#plang,)">

<xsl:call-template name="plang-page"/> </xsl:for-each>

</xsl:template>

Ключ instanceOf возвращает все экземпляры класса с заданным идентифи­катором темы класса:

<xsl:key

name = "instanceOf" match = "topic"

use = "instanceOf/topicRef/@xlink:href" />

Ключ topicByID возвращает все элементы topic по заданному идентифи­катору темы:

<xsl:key

name = "instanceOf" match = "topic"

use = "instanceOf/topicRef/@xlink:href" />

На рисунках выше видно, что все три шаблона верстки разбивают страницу на четыре прямоугольных области. Этим управляет общий главный шаблон страни­цы. Сначала мы просим процессор создать выходной файл относительно папки, заданной параметром $out-dir и формируем заголовок TITLE, помещая в него базовое имя текущей темы в естественном контексте. Последнее достигается сопос­тавлением с элементами topic в режиме label. Затем начинается процедура разби­ения страницы на четыре части. В левом верхнем углу создается гиперссылка на на­чальную страницу, ее текст – имя корневой темы в естественном контексте. Эту задачу решает применение шаблона к элементам topic в режиме link. В правом верхнем углу находятся ссылки на страницы языков программирования. Чтобы создать их, мы обходим все экземпляры темы programming language. В левом нижнем углу страницы под ссылкой на начальную страницу выводится часть кар­ты сайта, соответствующая классификации алгоритмов сортировки. Наконец, в основной части страницы (правый нижний угол) выводится содержимое, отно­сящееся к текущей теме, которая была передана в шаблон page в качестве пара­метра content:

<xsl:template name="page"> <xsl:param name="this"/> <xsl:param name="content"/>

<redirect:write select="concat($out-dir,$this/@id,’.html’)"> <HTML>

<HEAD> <TITLE>

<xsl:apply-templates select="$this" mode="label"/> </TITLE> </HEAD> <BODY>

<table width="1000" height="100%" cellspacing="0" cellpadding="10"> <tr>

<td width="250" height="20" bgcolor="#ffddbb" align="center">

<xsl:apply-templates select="$root" mode="link"/> </td>

<td width="750" height="20" valign="top" bgcolor="#eeeeee"> <table cellspacing="10"> <tr>

<xsl:for-each select="key(‘instanceOf’,,#plang,)"> <td background="grey">

<xsl:apply-templates select="." mode="link"/> </td> </xsl:for-each> </tr> </table> </td> </tr> <tr>

<td valign="top" bgcolor="#eeeeee"> <xsl:call-template name="sitemap">

<xsl:with-param name="classRef">#sort</xsl:with-param> <xsl:with-param name="current" select="$this/@id"/> </xsl:call-template> </td>

<td valign="top" bgcolor="#ffeedd" >

<xsl:copy-of select="$content"/> </td> </tr></table> </BODY> </HTML>

</redirect:write> </xsl:template>

Вот как шаблон применяется к элементам topic в режиме label:

<xsl:template match="topic" mode="label">

<xsl:value-of select="baseName[not(scope)]/baseNameString"/> </xsl:template>

А в режиме link элемент baseName используется для формирования гипер­ссылки на страницу темы:

<xsl:template match="topic" mode="link"> <a href="{@id}.html">

<xsl:value-of select="baseName[not(scope)]/baseNameString"/> </a> </xsl:template>

Ниже нам встретится также сопоставление в режиме subject-indicator, когда элемент baseName применяется для формирования гиперссылки на ресурс, индицирующий сопоставленную тему:

<xsl:template match="topic" mode="indicator">

<a href="{subjectIdentity/subjectIndicatorRef/@xlink:href}">

<xsl:value-of select="baseName[not(scope)]/baseNameString"/> </a> </xsl:template>

Шаблон sitemap обходит все подклассы темы sort, создает гиперссылки на страницы, соответствующие производным алгоритмам, и рекурсивно вызывает себя для обработки следующих в иерархии подклассов:

<xsl:template name="sitemap"> <xsl:param name="classRef"/> <xsl:param name="current"/>

<xsl:variable name="topic" select="key(‘topicByID’,$classRef)"/> <xsl:choose>

<xsl:when test="$topic/@id=$current"> <span class="A">

<xsl:apply-templates select="$topic" mode="label"/> </span> </xsl:when> <xsl:otherwise>

<xsl:apply-templates select="$topic" mode="link"/> </xsl:otherwise> </xsl:choose>

<xsl:variable name="aref" select="key(‘classAssoc’,$classRef)"/> <xsl:if test="$aref"> <ul>

<xsl:for-each

select="$aref/member

[roleSpec/topicRef/@xlink:href= ‘#_subclass’]/topicRef">

<li>

<xsl:call-template name="sitemap">

<xsl:with-param name="classRef" select="@xlink:href"/> <xsl:with-param name="current" select="$current"/> </xsl:call-template> </li> </xsl:for-each> </ul> </xsl:if> </xsl:template>

Ключ classRef, применяемый в этом шаблоне, использует идентификатор заданной темы для нахождения ассоциаций типа superclass-subclass, в ко­торых эта тема играет роль суперкласса:

<xsl:key

name = "classAssoc"

match = "association[instanceOf/topicRef/@xlink:href=

‘#_class-subclass’]"

use = "member[roleSpec/topicRef/@xlink:href=

‘#_superclass’]/topicRef/@xlink:href" />

Далее нам встретится еще ключ subClassRef, который также индексирует ассоциации superclass-subclass, но на этот раз возвращает элемент member, для которого заданная тема выступает в роли подкласса:

<xsl:key

name = "subClassAssoc"

match = "association[instanceOf/topicRef/@xlink:href=

‘#_class-subclass’]"

use = "member[roleSpec/topicRef/@xlink:href=

‘#_subclass’]/topicRef/@xlink:href" />

Теперь мы готовы к рассмотрению трех шаблонов верстки. Шаблон root-page совсем простой. Он вызывает описанный ранее шаблон page, передавая ему сгенерированную HTML-разметку для вхождения типа

description в параметре content:

<xsl:template name="root-page"> <xsl:param name="this"/> <xsl:call-template name="page">

<xsl:with-param name="this" select="$this"/> <xsl:with-param name="content"> <font size="+1">

<xsl:apply-templates

select="$this/occurrence

[instanceOf/topicRef/@xlink:href=’#description’]"/>

</font> </xsl:with-param> </xsl:call-template> </xsl:template>

Шаблон plang-page чуть сложнее. Он формирует заголовок, составлен­ный из имени текущей темы, за которой следует название ее типа. Далее идет строка, содержащая ссылку на то место в Web, где определен предмет темы. Затем выводятся описания темы, если таковые имеются. Ищутся и выводятся ссылки на все вхождения кода на текущем языке. После ресурса в квадратных скобках размещается ссылка на алгоритм сортировки, реализованный в этом ресурсе:

<xsl:template name="plang-page">

<xsl:param name="this" select="."/> <xsl:call-template name="page">

<xsl:with-param name="this" select="$this"/> <xsl:with-param name="content"> <font size="+2">

<xsl:apply-templates select="$this" mode="label"/>, a <xsl:apply-templates mode="label" select="key(‘topicByID’,$this/instanceOf/topicRef/@xlink:href)" />. </font> <br/><br/>

<xsl:apply-templates select="$this/subjectIdentity"/> <xsl:apply-templates

select="$this/occurrence

[instanceOf/topicRef/@xlink:href=’#description’]"/> <xsl:variable name="codes"

select="key(‘plang-codes’,concat(,#,,$this/@id))"/> <xsl:if test="$codes">

<span>Aлгоритмы сортировки, реализованные на языке

<xsl:apply-templates select="$this" mode="label"/>:</span> <ul>

<xsl:for-each select="$codes"> <li>

<a href="{resourceRef/@xlink:href}">

<xsl:value-of select="resourceRef/@xlink:href"/>

</a>

[<xsl:apply-templates select=".." mode="link"/>]<br/> </li> </xsl:for-each> </ul>

<br/><br/> </xsl:if> </xsl:with-param> </xsl:call-template>

</xsl:template>

Ключ plang-codes индексирует все вхождения в тематической карте по теме в том же контексте:

<xsl:key

name="plang-codes" match="occurrence"

use="scope/topicRef/@xlink:href"/>

Последним идет шаблон algorithm-page. Его заголовок состоит из имени текущей темы, за которым в квадратных скобках следуют имена тем, перечислен­ных в элементах also-known-as. За строкой идентификации предмета следует список суперклассов, которым наследует текущий алгоритм сортировки, если та­ковые имеются. За ним расположены одно или несколько описаний алгоритма, список ссылок на вхождения демонстраций работы алгоритма и список примеров кода с перекрестными ссылками на соответствующие им языки программирова­ния в квадратных скобках. В конце страницы располагается список подклассов или вариантов текущего алгоритма, если таковые имеются. И наконец шаблон algorithm-page вызывает себя самого для вывода страниц, описывающих под­классы текущего класса:

<xsl:template name="algorithm-page"> <xsl:param name="this"/> <xsl:call-template name="page"> <xsl:with-param name="this" select="$this"/> <xsl:with-param name="content">

<font size="+2"><xsl:apply-templates select="$this" mode="label"/> <xsl:if test="$this/baseName

[scope/topicRef/@xlink:href=’#also-known-as’]"> [<xsl:value-of select="$this/baseName

[scope/topicRef/@xlink:href=’#also-known-as’] /baseNameString"/>] </xsl:if> </font>

<br/><br/>

<xsl:apply-templates select="$this/subjectIdentity"/> <xsl:variable name="superclasses"

select="key(‘subClassAssoc’,concat(,#,,$this/@id)) member[roleSpec/topicRef/@xlink:href=’#_superclass’]/topicRef"/> <xsl:if test="$superclasses"> Inherits from

<xsl:for-each select="$superclasses"> <xsl:apply-templates

select="key(‘topicByID’,@xlink:href)" mode="link"/> <xsl:if test="position( ) != last( )">, </xsl:if> </xsl:for-each> <br/><br/> </xsl:if>

<xsl:apply-templates

select="$this/occurrence

[instanceOf/topicRef/@xlink:href=’#description’]"/> <xsl:variable name="demos" select="$this/occurrence

[instanceOf/topicRef/@xlink:href=’#demo’]"/> <xsl:if test="$demos">

<span>Демонстрации: </span> <ul>

<xsl:for-each select="$demos"> <li>

<a href="{resourceRef/@xlink:href}">< xsl:value-of select="resourceRef/@xlink:href"/> </a><br/> </li> </xsl:for-each> </ul> <br/> </xsl:if>

<xsl:variable name="codes"

select="$this/occurrence[instanceOf/topicRef/@xlink:href=’#code’]"/> <xsl:if test="$codes"> <span>Pеализации и примеры кода: </span> <ul>

<xsl:for-each select="$codes"> <li>

<a href="{resourceRef/@xlink:href}">

<xsl:value-of select="resourceRef/@xlink:href"/> </a>

[<xsl:apply-templates mode="link"

select="key(‘topicByID’,scope/topicRef/@xlink:href)"/>] </li> </xsl:for-each> </ul> <br/> </xsl:if>

<xsl:variable name="subclasses" select="key(‘classAssoc’,

concat(‘#’,$this/@id))/member

[roleSpec/topicRef/@xlink:href= ‘#_subclass’]/topicRef"/>

<xsl:if test="$subclasses"> See also

<xsl:value-of select="$this/baseName[not(scope)]/baseNameString"/> variants:

<xsl:for-each select="$subclasses"> <xsl:apply-templates

select="key(‘topicByID’,@xlink:href)" mode="link"/> <xsl:if test="position( ) != last( )">, </xsl:if> </xsl:for-each> </xsl:if> </xsl:with-param> </xsl:call-template> <xsl:variable name="aref"

select="key(‘classAssoc’,concat(,#,,$this/@id))"/> <xsl:for-each

select="$aref/member

[roleSpec/topicRef/@xlink:href=’#_subclass’]/topicRef"> <xsl:call-template name="algorithm-page">

<xsl:with-param name="this" select="key(‘topicByID’,@xlink:href)"/> </xsl:call-template> </xsl:for-each> </xsl:template>

Обсуждение

Topic Maps – это технология сбора и управления знаниями о различных пред­метных областях. В данном случае мы представили отношения между алгоритма­ми и другими объектами и ресурсами. Если скрупулезно следовать соглашениям, принятым в каркасе CTW, то из исходной тематической карты можно создать Web-сайт.

В приведенном решении мы ограничились небольшим количеством объектов и отношений между ними. Реальные приложения гораздо сложнее. Мы лишь ста­вили себе целью продемонстрировать огромные возможности, заложенные в кар­касе CTW.

В каркасе CTW единственный документ, содержащий тематическую карту, уп­равляет как содержанием, так и структурой целого сайта. Если карта организована правильно, то обеспечивается надежная и интуитивно понятная процедура поддер­жания ссылок между страницами, содержимого страниц и метаданных. Сайты, по­строенные с помощью каркаса CTW, легко объединяются и не страдают от пробле­мы «битых ссылок». Применение XSLT гарантирует единообразный внешний вид, независимость от платформы и возможность повторного использования.

За все эти удобства приходится платить: каркас CTW заставляет вас осмысли­вать содержимое в терминах тем, их характеристик и ассоциаций. Вы можете созда­вать содержимое только в рамках выбранной онтологии, но зато знания, представ­ленные на сайте, будут хорошо организованы, а навигация по ним удобна.

В основу CTW положен язык XSLT, потому что он обеспечивает модульные и удобные для сопровождения средства преобразования и стилизации знаний, со­держащихся в тематической карте. Динамические решения на базе CTW и XSLT масштабируются до нескольких тысяч тем, а статические ограничены только рас­полагаемым дисковым пространством.

См. также

XML Topic Maps: Creating and Using Topic Maps for the Web, под редакцией Jack Park, (Addison Wesley, 2002) – прекрасная книга, в которой в доступной форме рассматривается теория и практика применения тематических карт.

Хорошую подборку ссылок на ресурсы, посвященные тематическим картам, можно найти по адресу http://www.dmoz.org/Computers/Artificial_Intelligence / Knowledge_Representation/Topic_Maps/.

Автор поддерживает сайт http://www.cogx.com/ctw, где также есть материалы о тематических картах и каркасе CTW. Слайды с презентации CTW на конференции Extreme Markup Languages находятся по адресу http://www.cogx.com/Extreme2000/.

Мангано Сэл  XSLT. Сборник рецептов. – М.: ДМК Пресс, СПБ.: БХВ-Петербург, 2008. – 864 с.: ил.

По теме:

  • Комментарии