E-learning a DocBook

Jan Pavlovič

Fakulta informatiky Masarykova univerzita v Brně



Botanická 68a
602 00
Brno

Přehled revizí
Revize 1.58. května 2003JP
úprava rozsahu na 10 str.
Revize 1.46. května 2003TP
přidán xincluder-fi
Revize 1.36. května 2003JP
oprava gramatických chyb
Revize 1.25. května 2003JP
upravení struktury dokumentu
Revize 1.14. května 2003TP
přidán úvod a slidy
Revize 1.029. dubna 2003JP
první verze

Abstrakt

Tento příspěvek ukazuje další možnosti využití DocBooku (DB) v elektronické podpoře výuky. Ilustruje použití DB zejména při tvorbě studentských prací a slidů pro přednášející. Seznamuje s XML katalogy, adaptací DTD DocBooku a s rozšířeními nástrojů pro práci s XML XInclude.


Odkaz na DTD, který uvádíme v hlavičce XML souboru je řešen pomocí dvou různých identifikátorů. Nejprve uvedeme veřejný identifikátor: PUBLIC, který označuje obecně používanou identifikaci gramatiky, nicméně neříká nic o jejím fyzickém uložení. Právě k tomu slouží systémový identifikátor: SYSTEM, který obsahuje konkrétní odkaz na gramatiku. Jelikož systémový identifikátor vždy následuje za veřejným identifikátorem, neuvádí se klíčové slovo SYSTEM.

DTD neslouží pouze ke kontrole validity dokumentu, ale i pro substituce entit, např. entita ‐ (HYPHEN-MINUS) se podle odkazu entit v DTD nahradí atd. Proto je nezbytné odkaz na DTD v XML souboru uvést. Stahování celého DTD z webu pokaždé, když chceme transformovat dokument, by bylo značně pomalé a neefektivní. Lepší bude zapsat do systémového identifikátoru cestu k lokálně uložené kopii DTD. Tím pádem můžeme používat dokument i off-line. Problém ale nastane, pokud se bude používat dokument na jiném systému, kde je původní odkaz na lokální DTD neplatný. Přepisovat pokaždé hodnotu systémového identifikátoru by bylo nepraktické, dokonce uživatel ani nemusí vědět, kde je DTD v systému uloženo. Naštěstí lze celou situaci jednoduše a elegantně řešit pomocí katalogů.

Katalogové soubory [1] jsou svým způsobem referenční tabulky. Obsahují odkazy na lokálně umístěné entity v závislosti na veřejném identifikátoru (umí i různé přepisování kontextu). Jediné co se musí procesoru sdělit je, kde se patřičný katalogový soubor nachází a on si v závislosti na získaných informacích sám načte lokálně uložené entity.

Bohužel většina XML parserů a XSLT procesorů podporující katalogy má vlastní formu jak mapovat lokální entity (hlavně pod systémy Windows). Naštěstí množiny řešení nejsou úplně disjunktní.

V souboru catalog.xml je řečeno, že DTD označené veřejným identifikátorem:

-//OASIS//DTD DocBook XML V4.2//EN

se má načíst z lokálně uloženého souboru:

file:///c:/xml-dev/docbook/4.2/docbookx.dtd

XSLT procesorům musíme sdělit, že hodláme používat katalogy a kde je mají hledat.

xmllint, xsltproc [2] patří mezi nejznámější parsery a procesory, díky své binární podobě jsou velice rychlé. Nativně umožňují použití katalogů. Stačí nastavit systémovou proměnou:

XML_CATALOG_FILES=/path/catalog.xml

Xalan [3] a ostatní procesory napsané pod Javou používají katalogy tak, že se procesoru zadájí jména externích tříd, které za ně mají mapování entit provést. Pro používání katalogů je nezbytný katalogový nástroj [4]. Jeho třídy se předají procesoru jako parametry. Catalog resolver má vlastní konfigurační soubor CatalogManager.properties, ve kterém lze nastavovat kromě cesty ke katalogům i několik jiných užitečných voleb.

Do CLASSPATH přidáme cestu k adresáři, kde je soubor CatalogManager.properties a cestu k resolveru resolver-1.0.jar

CLASSPATH=/xalan_files:/path_to_CatalogManager.properties:resolver-1.0.jar

při transformaci použijeme parametry:

-ENTITYRESOLVER org.apache.xml.resolver.tools.CatalogResolver
-URIRESOLVER org.apache.xml.resolver.tools.CatalogResolver 

Pro zjištění použité verze Xalanu stačí uvést parametr -V. Nicméně SUN připravil menší překvapení v tom, že integroval (dnes již hodně historickou) verzi Xalanu přímo do JDK. Což samozřejmě nechceme a proto musíme Javě říci, že má Xalan hledat nejprve někde jinde. Stačí použít přepínač:

-Xbootclasspath/p:xalanfiles:resolver:CatalogManager.propertiesdir

Saxon [5] má soubor CatalogManager.properties samozřejmě stejný a CLASSPATH nastavíme obdobně jako u Xalanu. Při transformaci použijeme parametry:

-x org.apache.xml.resolver.tools.ResolvingXMLReader
-y org.apache.xml.resolver.tools.ResolvingXMLReader
-r org.apache.xml.resolver.tools.CatalogResolver

Bohužel parser Saxonu Ælfred to s katalogy moc neumí, je nutné použít jiný parser například Crimson nebo Xerces, přidáme jej do CLASSPATH a použijeme parametry:

-Djavax.xml.parsers.DocumentBuilderFactory=
   org.apache.crimson.jaxp.DocumentBuilderFactoryImpl
-Djavax.xml.parsers.SAXParserFactory=
   org.apache.crimson.jaxp.SAXParserFactoryImpl

XInclude [6] je standard pro vkládání textu do XML souborů, nabízí mnohem elegantnější a silnější prostředek než je vkládání pomocí entit:

<!ENTITY intro "intro.xml"/>

Při vkládání dokumentů jako entity jsme nemohli uvádět DOCTYPE a XML soubory nebyly tak plnohodnotné a nešly validovat. S XInclude tento problém odpadá. Navíc můžeme pomocí Xpointer odkazu stanovit, kterou část dokumentu vložit, vybrat si zdali dokument vložit jako text nebo jako XML kód a ošetřovat případy, kdy se vložení nepodařilo.

Elementy použité pro XInclude patří do vlastního jmenného prostotu, který musí být všude v dokumentu stejný.

<xi:include xmlns:xi="http://www.w3.org/2001/XInclude" 
   href="intro.xml"/>

Dokument nemusíme vkládat celý, ale třeba jen danou kapitolu, nejednodušší způsob je použít ID dané kapitoly.

<xi:include xmlns:xi="http://www.w3.org/2001/XInclude" 
   href="intro.xml#Installing"/>

Mnohem více lze docílit, pokud použijeme Xpointer ukazatel na požadovanou část dokumentu, pomocí Xpath syntaxe.

<xi:include xmlns:xi="http://www.w3.org/2001/XInclude" 
   href="intro.xml#xpointer(/sect1/section[1]/*)"/>

XInclude můžeme použít i ke vkládání prostého textu. Atribut parse="text" sdělí procesoru, aby daný obsah namísto XML zobrazil jako prostý text. Tím jsou speciální XML znaky převedeny na odpovídající entity:

& na &amp;
< na &lt;
> na &gt;
" na &quot;

<programlisting>
<xi:include xmlns:xi="http://www.w3.org/2001/XInclude" 
   href="code.c" parse="text"/>
</programlisting>

Při vkládání prostého textu můžeme využít rozšířené interpretace URL vkládaného souboru. V URL textového souboru nemají standardně znaky za # žádný speciální význam např. code.c#1 je běžně interpretováno stejně jako code.c. Prostor za # proto využijeme ke specifikaci, které řádky ze vstupního souboru vložit, např.:

#2

vloží pouze druhý řádek

#2-

vloží od druhého řádku počínaje všechny řádky

#2-5

vloží řádky od druhého do pátého včetně

#2$3

vloží tři řádky počínaje druhým

#-2

vloží první dva řádky

#$2

vloží první dva řádky

Toto rozšíření samozřejmě nefunguje automaticky v každém XInclude procesoru. V Javě je možno použít místo nástroje xincluder.jar [7] jeho vylepšenou verzi xincluder-fi.jar vyvinutou na pracovišti autorů tohoto článku.

Pokud vložení neproběhne správně, ať už z důvodu, že daný soubor neexistuje nebo jej nelze stáhnout, lze namísto prázdného xi:include elementu vložit na dané místo vlastní chybové hlášení.

<xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="intro.xml">
  <xi:fallback>
    <para><emphasis>CHYBA: XINCLUDE</emphasis></para>
  </xi:fallback>
</xi:include>

Ve skutečnosti může xi:fallback obsahovat další xi:include element, který se procesor pokusí vyhodnotit v případě neúspěchu. Nesmíme však zapomenout, že pokud uvedeme xi:fallback, tak se transformace dokumentu v případě chyby nezastaví. Pokud je nezbytné, aby vložení souboru proběhlo, je lepší xi:fallback element nepoužívat a nechat proces skončit s chybou.

Jednou z hlavních výhod XInclude je, že můžeme jednotlivé soubory zvlášť validovat. Avšak xi:include element není validní element DocBooku a tím pádem nepůjde hlavní dokument zvalidovat. Jsou dva způsoby jak tento problém vyřešit. 1) Nejprve celý dokument sestavíme a poté provedeme validaci.

xmllint --noout --xinclude --postvalid file.xml

Pokud chceme použít XInclude pod Javou je potřeba si opatřit XInclude nástroj [7].

java -cp xincluder.jar:xercesImpl.jar com.elharo.xml.xinclude.SAXXIncluder file.xml > file-ok.xml

2) Upravíme DTD DocBooku tak, aby obsahovalo patřičné xi:include elementy.

DTD DocBooku je postavené na parametrových entitách, což jistou měrou omezuje specifikaci struktury dokumentu, ale na druhou stranu to umožňuje snadnou modifikaci. Skládáním a přidáváním jednotlivých parametrových entit můžeme do DTD přidat požadované úpravy.

Malou modifikací DTD DocBooku lze přidat gramatiku XInclude a umožnit tak validovat dokumenty, které obsahují xi:include elementy. Nejprve uvedeme definici parametrových entit xmlns.xi a xml.base se specifikací jmenných prostorů pro XInclude a xml:base (slouží k možné definici prefixu URI). Dále vlastní deklaraci elementů xi:include. Jelikož pouhá definice elementů nestačí, musíme ještě specifikovat, kde se mohou elementy xi:include v dokumentu vyskytovat. Díky modulární architektuře DTD DocBooku stačí přidat xi:include k několika patřičným parametrovým entitám. Nakonec ještě přidáme jmenné prostory xi:include a xml:base do běžných atributů. Tím pádem nemusíme v dokumentu deklarovat jmenný prostor xi:include a můžeme psát:

<xi:include href="intro.xml"/>

Naše úpravy uložíme do samostatného souboru například: xinclude.mod, který k DTD DocBooku, aniž bychom museli zasahovat do originální struktury, připojíme jako entitu.

<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN" 
   "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd" [
<!ENTITY % xinclude SYSTEM "http://www.fi.muni.cz/fithesis/xinclude.mod">
   %xinclude; ]>

Jak je patrné, není úprava DTD nic těžkého a můžeme tedy v případě potřeby přidat několik elementů. Například chceme-li použít DocBook pro tvorbu bakalářských a diplomových prací, je vhodné obohatit DTD o několik elementů jako: vedoucí práce, název fakulty, pohlaví studenta, poděkování atd.

Je dobré XML hlavičku minimalizovat. Proto, když máme více souborů s úpravami DTD, je lepší buď úpravy dát do jediného souboru nebo je použitím entit integrovat.

Jelikož mají bakalářské a diplomové práce dokumentační ráz (dokumentujeme buď výtvor, objev nebo technologie) můžeme k jejich vytváření bez problémů použít právě DocBook. Přinese nám to hned několik výhod. Autor práce se nemusí v době psaní zatěžovat výsledným vzhledem dokumentu, neboť zapisuje pouze údaje s informační hodnotou. K psaní práce stačí obyčejný editor, který umí zvýrazňovat syntaxi a tím se stává tvorba platformně nezávislá. Výstup do tištěné podoby je realizován typografických procesorem LaTeX. Autor tak bez větších znalostí LaTeXu a hlubších znalostí typografie získá kvalitní dokument. Navíc lze do průběhu transformace začlenit i patřičnou LaTeXovou stylovou třídu, která sjednocuje rámcový vzhled všech prací na dané fakultě. Dále autor získá HTML prezentaci své práce, která se opět dá standardizovat pomocí CSS stylů. Fakulta může takovéto práce snadno klasifikovat a provádět nad nimi fulltextové vyhledávání.

Abychom docílili zmíněných vlastností prací psaných v DocBooku, je nutné provést několik úprav. Jednak musíme upravit DTD DocBooku přidáním několik elementů k zápisu informací typických pro bc. a dipl. práce. K rozšíření nám bude stačit soubor s výše jmenovanými úpravami: fithesis.mod.

Dále musíme rozšířit XSLT styly. Přidat šablony pro titulní stranu v HTML a upravit výstup do LaTeXu tak, aby v něm byly začleněny úpravy pro použití fakultního stylu používaného pro závěrečné práce. Celé řešení je možné jednoduše použít na jakékoli univerzitě či fakultě. Spolu s ukázkami hotových prací a dokumentací je systém pro tvorbu bakalářských a diplomových prací k dispozici na http://www.fi.muni.cz/~xpavlov/xml

Norman Walsh připravil pod názvem DocBook Slides (viz [8]) derivát zjednodušeného DocBooku (Simplified DocBook) určený k přípravě prezentačních podkladů (slidů). Současně k nim poskytuje rozsáhlou sadu XSL stylů pro vizualizaci fólií.

Studenti často vyžadují, aby slidy dostali k dispozici i v tisknutelné podobě. Pro tyto případy lze použít buďto existující styly formátující slidy do XSL:FO (jsou k dispozici na http://sourceforge.net/projects/docbook vedle stylů generujících HTML) a výsledný soubor převést např. procesorem Apache FOP do PDF souboru a ten vytisknout. Nebo použít db2latex styly pro Slides a trasformovat slidy do LaTeXu. Velmi jednoduchým XSLT stylem je také možno převést slidy do normálního DocBooku např. jako knihu (book), případně doplňovat ako běžný DB dokument. Tento způsob se osvědčil nejlépe ne každý student totiž chce celý soubor tisknout, někomu vyhovuje jeho prohlížení a to i např. na počítačích třídy PDA, pro které neexistuje prohlížeč PDF.

Ohledně členění jednotlivých přednášek do souborů DB Slides se v praxi osvědčila tato struktura:

  1. Co přednáška (např. dvouhodinová), to jeden soubor slides (snadná modifikace jednotlivých přednášek).

  2. Slidy struktura celého předmětu je popsána zvláštním souborem, kde jsou kromě slidů zařazeny i odkazy na další komponenty plné učební texty a jejich části (nejen slidy pro přednášejícího), větší příklady, testy, atd. To umožňuje snadnou správu celkové struktury předmětu.

  3. Jedna speciální „přednáška“ pak představuje osnovu celého kurzu a odkazuje se na slidy k jednotlivým skutečným přednáškám.

    Kromě odkazů je tam totiž možné vložit i další informace, uváděné typicky v úvodní přednášce předmětu, kdy se studenti seznamují s osnovou předmětu.

[2] Gnome. . Libxml2. http://xmlsoft.org.

[3] Apache. . Xalan. http://xml.apache.org/xalan-j.

[4] Apache. . Catalog Resolver. http://xml.apache.org/dist/commons/resolver-1.0.jar.

[5] Michael H. Kay. Saxon. http://saxon.sf.net.

[6] W3 Consorcium. . XML Inclusion Proposal (XInclude). http://www.w3.org/TR/xinclude.

[8] Norman Walsh. DocBook Open Repository Project. http://docbook.sourceforge.net.

[9] Petr Šaloun. Akademický server pro distanční vzdělávání. In Proc. of Technologie pro e-vzdělávání, ČVUT Praha, VŠB-TU Ostrava, květen 2002.