Encje i pliki catalog, czyli fizjologia XML-a
Mówimy często potocznie „plik XML”. Tymczasem zawartość dokumentu XML rzadko zapisywana jest w pojedynczym pliku. Co więcej, fizycznym miejscem przechowywania dokumentu XML nie muszą być wcale pliki, ale na przykład rekordy w bazie danych. Przyjrzyjmy się więc, jak wygląda fizyczna strona dokumentów XML i jak organizować ją w sposób efektywny i elastyczny.
Autorzy: Andrzej Dmoch, Szymon Zioło
Źródło: Software Developer’s Journal 06/2004 (114) http://sdjournal.org
Pliki, encje, dokumenty
Zacznijmy od uporządkowania terminologii. Fizycznym miejscem przechowywania dokumentu zwykle jest plik na dysku, lecz może to być w ogólności zupełnie inny obiekt, na przykład zasób w Internecie czy rekord w bazie danych. Dlatego powinniśmy używać bardziej ogólnego pojęcia encja (ang. entity), obejmującego wszystkie fizyczne metody przechowywania porcji informacji. Logiczną jednostką informacji, jaką się zwykle posługujemy, jest dokument. Najczęściej utożsamiany go z konkretnym plikiem na dysku, lub – wedle nowej terminologii – z encją, aczkolwiek bardzo często treść dokumentu jest rozproszona w wielu encjach. Zawsze jednak wyróżniamy jedną szczególną encję – encję dokumentu (ang. document entity), która ewentualnie odwołuje się do innych encji („inkluduje” je). Z dokumentem XML zwykle stowarzyszony jest opis jego struktury – definicja typu dokumentu DTD lub schemat XML Schema. DTD jest formalnie częścią dokumentu i może być umieszczona bezpośrednio w encji dokumentu, co obrazuje przykład z Listingu 1. DTD jest jednak z reguły wspólna dla całej kolekcji dokumentów, zatem błędem byłoby przechowywanie osobnej jej kopii w encji każdego dokumentu. Typowym rozwiązaniem jest więc umieszczanie DTD w osobnej encji i odwoływanie się do niej z encji poszczególnych dokumentów (Listing 2). Napis umieszczony w odwołaniu po słowie SYSTEM jest tzw. identyfikatorem systemowym (ang. system identifier), wskazującym fizyczne położenie encji DTD, na przykład ścieżką do pliku w systemie plików, lub identyfikatorem rekordu w bazie danych. Powiedzieliśmy, że DTD jest zwykle wspólna dla całej klasy dokumentów. Tymczasem pewne deklaracje występujące w DTD (na przykład deklaracje encji) mają charakter wybitnie lokalny i są związane z konkretnym dokumentem. Tym razem błędem byłoby umieszczanie ich w encji DTD wspólnej dla wielu dokumentów. Na szczęście jest na to sposób: lokalną, specyficzną dla dokumentu grupę deklaracji można umieścić w encji dokumentu, nie rezygnując z odwołania do encji DTD (Listing 3). W ten sposób DTD uległa podziałowi na dwie części: wewnętrzny podzbiór DTD (ang. internal DTD subset) i zewnętrzny podzbiór DTD (ang. external DTD subset). Warto mieć świadomość, że to, co potocznie nazywamy „plikiem DTD”, często jest jedynie częścią DTD, uzupełnianą i modyfikowaną w encji dokumentu. Listing 3 pokazuje przy okazji, że zastosowanie encji nie ogranicza się jedynie do dołączania zewnętrznego podzbioru DTD. Zadeklarowana w nim encja refren służy do dołączenia refrenu pamiętanego w osobnym pliku sonet102-refren.xml. Dochodzimy w tym miejscu do kluczowego rozróżnienia na dwa – spokrewnione ze sobą, ale jednak różne – znaczenia terminu encja. Do tej pory mówiliśmy o encji jako wspólnym terminie dla pliku, rekordu w bazie danych, zasobie internetowym czy innym sposobie przechowywania porcji informacji w systemie. Ale encja to także odwołanie do takiego pliku, rekordu, zasobu, umieszczone w treści dokumentu XML. Różne znaczenia terminu encja ilustruje Rysunek 1.
Listing 1. Dokument wraz z DTD
<?xml version=”1.0″?>
<!DOCTYPE wiersz [
<!ELEMENT wiersz (autor, tytul, zwrotka*)>
<!ATTLIST wiersz bialy (tak|nie) ”nie”>
<!ELEMENT autor (#PCDATA)>
<!ELEMENT tytul (#PCDATA)>
<!ELEMENT zwrotka (wers)*>
<!ELEMENT wers (#PCDATA)>
]>
<wiersz>
<autor>William Shakespeare</autor>
<tytul>Sonet CCII</tytul>
<zwrotka>…</zwrotka>
<wiersz>
———————————-
Listing 2. Dokument z odwołaniem do DTD
<?xml version=”1.0″?>
<!DOCTYPE wiersz SYSTEM „wiersz.dtd”>
<wiersz>
<autor>William Shakespeare</autor>
<tytul>Sonet CCII</tytul>
<zwrotka>…</zwrotka>
<wiersz>
Charakterystyka encji
Dostępne są następujące rodzaje encji:
- encje wewnętrzne (ang. internal entities) – definiowane w miejscu deklaracji encji, na przykład: <!ENTITY xml „Extensible Markup Language”>
- encje zewnętrzne (ang. external entities) – definiowane jako odwołania do zasobów (na przykład plików) w systemie: <!ENTITY refren SYSTEM „sonet102-refren.xml”>
- encje przetwarzane (ang. parsed entities) – encje, których zawartość jest dołączana do treści dokumentu i analizowana przez parser XML,
- encje nieprzetwarzane (ang. unparsed entities) – odwołania do obiektów binarnych, na przykład plików graficznych: <!ENTITY logo SYSTEM „logo.gif” NDATA „GIF”>
- encje ogólne (ang. general entities) – wykorzystywane w treści dokumentu,
- encje parametryczne (ang. parameter entities) – wykorzystywane w DTD do jego modularyzacji i parametryzacji, na przykład: <!ENTITY % inline „(#PCDATA | emph | keyword | name)*”> <!ELEMENT para %inline;>
Każda encja posiada trzy spośród wymienionych cech: jest wewnętrzna lub zewnętrzna, jednocześnie jest przetwarzana bądź nie, oraz ogólna lub parametryczna. Jednak dopuszczalne są tylko następujące kombinacje:
Identyfikatory publiczne i systemowe
W dotychczasowych przykładach odwoływaliśmy się do encji zewnętrznych podając tzw. identyfikator systemowy, będący najczęściej ścieżką w systemie plików. W profesjonalnych zastosowaniach nie jest to rozwiązanie pożądane, gdyż może powodować utratę elastyczności i przenośności dokumentów pomiędzy systemami. Gdyby plik zawierający DTD znajdował się w dwóch systemach komputerowych w różnych lokalizacjach, to przeniesienie dokumentu z jednego systemu na drugi oznaczałoby konieczność modyfikacji jego treści! Dlatego rekomendacja XML wprowadza – oprócz identyfikatorów systemowych – tzw. identyfikatory publiczne (ang. public identifiers), niezależne od położenia w systemie encji opisywanej takim identyfikatorem. Po identyfikatorze publicznym musi jednak wystąpić także identyfikator systemowy, na przykład: <!ENTITY refren PUBLIC „-//Software//TEXT Sonet 102 Refren//PL” „sonet102-refren.xml”> Identyfikatory publiczne – jako że mają wskazywać encje niezależnie od ich fizycznego położenia w systemach – powinny być zrozumiałymi i unikatowymi nazwami tych encji. Jak jednak zapobiec przypadkowemu użyciu tego samego identyfikatora przez kilka osób lub organizacji do opisania różnych encji? W SGML-u stosuje się tzw. formalne identyfikatory publiczne (ang. formal public identifiers) o określonej wewnętrznej składni. Warto ją stosować także dla identyfikatorów encji XML-owych. Wtedy szansa przypadkowego użycia tego samego identyfikatora do oznaczenia dwóch różnych encji jest minimalna. Zgodnie z tą składnią, identyfikator publiczny składa się z kilku sekcji, oddzielonych od siebie znakami //. Początek identyfikatora to określenie właściciela encji. Nazwa właściciela może być zarejestrowana bądź nie. Zarejestrowaną nazwę należy poprzedzić znakami +//. Takie nazwy są kontrolowane przez organizację dbającą o ich unikalność. Najprościej jest jednak używać nazw niezarejestrowanych, poprzedzonych znakami -//. Jeśli zawartość encji opisywanej identyfikatorem jest standardem ISO, wówczas zamiast nazwy właściciela podajemy numer ISO tego standardu. Sami zapewne z tej możliwości nie skorzystamy, ale na pewno spotkamy wiele identyfikatorów publicznych posiadających ISO jako „właściciela”. Kolejną sekcją formalnego identyfikatora publicznego jest słowny opis zawartości encji. Powinien się on zaczynać od jednego z kilku standardowych słów, opisujących rodzaj zawartości: l DTD, l ENTITIES – zbiór deklaracji encji, najczęściej definiujących niestandardowe znaki, l NOTATION – opis formatu notacji, l TEXT. Ostatnia sekcja to dwuliterowe określenie języka, w jakim zapisano treść encji (na przykład EN – angielski, PL – polski). Oto przykłady kilku standardowych, powszechnie używanych identyfikatorów: l -//USA-DOD//DTD Table Model 951010//EN – model tabel CALS, opracowany przez Departament Obrony USA, l -//W3C//DTD XHTML 1.0 Strict//EN – DTD dla dokumentów XHTML, l -//TopicMaps.org//DTD XML Topic Map (XTM) 1.0//EN – DTD dla map wiedzy Topic Maps, l ISO 8879:1986//ENTITIES Greek Symbols XML//EN – zbiór deklaracji standardowych encji dla alfabetu greckiego. Opisane reguły tworzenia formalnych identyfikatorów nie są oczywiście weryfikowane przez parsery. Identyfikator publiczny jest dla narzędzi programistycznych po prostu ciągiem znaków. Reguły zaś mają nam jedynie pomóc uniknąć przypadkowej zbieżności identyfikatorów.
Listing 3. Dokument z wewnętrznym podzbiorem DTD
<?xml version=”1.0″?>
<!DOCTYPE wiersz SYSTEM „wiersz.dtd” [
<!ENTITY refren SYSTEM "sonet102-refren.xml">
]>
<wiersz>
<autor>William Shakespeare</autor>
<tytul>Sonet CCII</tytul>
<zwrotka>…</zwrotka>
&refren;
<wiersz>
——————————–
Listing 4. Główny plik catalog w systemie sigmalink (fragmenty)
PUBLIC „-//ArborText//DTD Basic Report 930801//EN”
„dtd/report/report.dtd”
PUBLIC „-//empolis//DTD SLdemo Report//EN”
„dtd/sldemo/sldemo.dtd”
PUBLIC „-//empolis//DTD Virtual SLdemo Report//EN”
„dtd/sldemo/sldemo.dtd”
PUBLIC „-//empolis//ENTITIES SLdemo section//EN”
„dtd/section/section.dtd”
PUBLIC „-//empolis//ENTITIES SLdemo topic//EN”
„dtd/topic/topic.dtd”
PUBLIC „-//empolis//ENTITIES SLdemo subtop//EN”
„dtd/subtop/subtop.dtd”
PUBLIC „-//empolis//DTD SigmaLink Table V.1.2//EN”
„dtd/api/sl_tbl.dtd”
PUBLIC „-//empolis//DTD SigmaLink Link
Information//EN”
„dtd/api/sl_link.dtd”
PUBLIC „-//empolis//DTD SigmaLink
Dictionaries V.1.0//EN”
„dtd/api/sl_dicts.dtd”
PUBLIC „-//SYNEX INFORMATION AB//DTD WEB V2.00//EN”
„dtd/sl_web/sl_web.dtd”
PUBLIC „-//empolis//DTD DocBook XML CALS Table
Model V4.1.2//EN” „dtdents/tables/calstblx.dtd”
PUBLIC „-//empolis//DTD XML Exchange Table Model
19990315//EN” „dtdents/tables/soextblx.dtd”
Pliki catalog
Jak można wykorzystać identyfikatory publiczne do wskazywania położenia encji w konkretnym systemie, skoro z definicji są one niezależne od systemu? Potrzebujemy mechanizmu, który pozwoli nam odwzorować identyfikatory publiczne na fizyczne lokalizacje encji. Mechanizm taki jest powszechnie stosowany w systemach SGML-owych i jest zwykle konfigurowany przy pomocy specjalnych plików odwzorowujących identyfikatory publiczne na systemowe. Zwyczajowo pliki takie noszą nazwę catalog. Pliki catalog mogą występować w dwóch formatach. Częściej używany jest ten starszy, tekstowy, odziedziczony po SGML-u. Wpis odwzorowujący identyfikator publiczny na systemowy ma w tym formacie postać: PUBLIC „-//Software//DTD wiersz//PL” „dtd/wiersz.dtd” Nowszy format wykorzystuje składnię XML, na przykład: <public publicId=”-//Software//DTD wiersz//PL” uri=”dtd/wiersz.dtd”/> Identyfikatory systemowe używane w takich wpisach to oczywiście najczęściej ścieżki do plików. Mogą to być ścieżki bezwzględne, lub – jak w powyższym przykładzie – ścieżki względne. W przypadku ścieżek względnych lokalizacja pliku określona jest względem położenia pliku catalog, w którym znajduje się deklaracja. Pliki catalog mogą zawierać odwołania do innych plików catalog, co pozwala tworzyć swoistą hierarchię takich plików. Mechanizm ten jest przydatny zwłaszcza wtedy, gdy chcemy wykorzystać gotowe, zaawansowane zastosowanie XML-a, dostarczane z własnym plikiem catalog. Odwołanie „inkludujące” zewnętrzny plik catalog ma w składni tradycyjnej postać: CATALOG „calsdtd/catalog” zaś w składni XML: <nextCatalog catalog=”calsdtd/catalog”/> Dopuszczalne są oczywiście odwołania zagnieżdżone. W plikach catalog można też umieszczać komentarze, które w składni tradycyjnej muszą być poprzedzone znakami ––, na przykład: –– to jest komentarz Jeśli w strukturze plików catalog ten sam identyfikator publiczny wystąpi więcej niż raz, to znaczące będzie wystąpienie pierwsze w kolejności czytania.
Organizacja DTD
Rzadko zdarza się, żeby w zastosowaniach komercyjnych DTD była fizycznie jednym plikiem. Dużo częściej ma ona budowę modułową, gdzie poszczególne pliki mogą zawierać na przykład deklaracje encji znakowych czy oddzielne moduły tabel lub wyrażeń matematycznych. Wynika to między innymi z faktu, że twórcy DTD używają gotowych, publicznie dostępnych modułów, które stają się częściami większej całości. Komercyjna DTD jest więc zwykle zbiorem plików powiązanych przy pomocy odwołań do encji zewnętrznych poprzez identyfikatory publiczne. Gdyby nie pliki catalog, takie powiązania musiałyby być realizowane przy użyciu fizycznych ścieżek do plików. Same pliki catalog – dzięki możliwości „inkludowania” innych plików catalog – mogą tworzyć strukturę hierarchiczną. Zobaczmy, jak taka struktura plików catalog oraz opisywana przez nią organizacja DTD może wyglądać w konkretnym zastosowaniu. System sigmalink firmy empolis jest systemem zarządzania dokumentami, pozwalającym w szczególności na przechowywanie i edycję dokumentów XML. Administrator systemu musi więc mieć możliwość skonfigurowania własnych DTD, opisujących struktury dokumentów przechowywanych w systemie. Do tego dochodzą rozpowszechniane wraz z systemem predefiniowane moduły DTD, takie jak moduły tabel i zbiory deklaracji encji, oraz przykładowe DTD. W skład środowiska klienckiego użytkownika systemu sigmalink wchodzi między innymi edytor XML-owy Epic lub XMetaL oraz przeglądarka dokumentów XML. Choć oba komponenty służą do edycji i wyświetlania tych samych dokumentów, każdy z nich wymaga nieco innej konfiguracji. Wymusza to określoną strukturę plików catalog oraz samych DTD. Podstawowa konfiguracja środowiska XML-owego na stacji klienckiej sigmalinku, obejmująca jedynie struktury systemowe (bez DTD definiowanych na potrzeby konkretnego wdrożenia), składa się z konfiguracji bazowej, umieszczonej w katalogu SGML (nazwa historyczna), oraz z konfiguracji specyficznych dla edytora i przeglądarki XML, znajdujących się odpowiednio w katalogach Editor i Viewer. Konfiguracja bazowa pogrupowana jest w katalogi, zawierające: l standardowe DTD rozprowadzane wraz z sigmalinkiem (dtd); większość podkatalogów katalogu dtd zawiera po jednym pliku z definicją DTD, l moduły DTD do wykorzystania we własnych strukturach (dtdents), l zbiory deklaracji encji znakowych (iso). Najistotniejsze fragmenty głównego pliku catalog przedstawione są na Listingu 4. Konfiguracja przeglądarki XML korzysta z bazowej konfiguracji, dodając do niej własne systemowe DTD i zbiory deklaracji encji. Konfiguracja ta zawiera własny plik catalog, umieszczony w katalogu Viewer/catalog. Plik ten zawiera odwzorowania identyfikatorów publicznych specyficznych dla przeglądarki oraz odwołanie do bazowego pliku catalog: CATALOG „../../SGML/catalog” Inaczej jest z konfiguracją edytora Epic. Każdą DTD wykorzystywaną przez Epic konfiguruje się dodatkowymi plikami konfiguracyjnymi, edytor zaś kompiluje te pliki. Dlatego katalog Editor/Epic4.3/dtd zawiera kopię bazowej struktury katalogów z DTD, w której każdy podkatalog przechowuje komplet plików konfiguracyjnych danej DTD oraz jej wersję skompilowaną. W związku z tym plik catalog znajdujący się w katalogu Editor/Epic4.3 zawiera pełną listę odwzorowań identyfikatorów publicznych i nie odwołuje się do bazowego pliku catalog. Bazowa konfiguracja została więc wykorzystana wyłącznie przez przeglądarkę XML. Warto ją jednak utrzymywać jako odrębną strukturę, choćby po to, aby użyć jej podczas integrowania innego edytora, który nie będzie wymagał dodatkowych zasobów poza bazową DTD. Konfigurację specyficzną dla konkretnego wdrożenia sigmalinku warto oddzielić od konfiguracji systemowej, na przykład umieszczając ją w osobnych podkatalogach wewnątrz katalogów SGML, Editor/Epic4.3 i Viewer, lub wręcz tworząc zupełnie nowy katalog obok głównego katalogu SGMLConf. Konfiguracja ta powinna zawierać swoje pliki catalog. W bazowym pliku SGMLConf/SGML/catalog oraz niezależnym pliku SGMLConf/Editor/Epic4.3/catalog wystarczy wówczas jedynie umieścić odwołania do odpowiednich plików catalog specyficznych dla wdrożenia. Rysunek 2 przedstawia jeden z możliwych sposobów rozszerzenia konfiguracji sigmalinku o własne DTD. Zaznaczono na nim położenie plików catalog oraz odwołania pomiędzy nimi.
Listing 5. Dostosowanie parsera do obsługi plików catalog (źródło: http://www.arbortext.com/html/issue_three.html)
import com.arbortext.catalog.*;
…
CatalogEntityResolver cer =
new CatalogEntityResolver();
Catalog myCatalog = new Catalog();
myCatalog.loadSystemCatalogs();
cer.setCatalog(myCatalog);
…
myParser.setEntityResolver(cer)
Pliki catalog a parsery XML
Wiemy już niemal wszystko na temat wykorzystania plików catalog i identyfikatorów publicznych do identyfikowania DTD w sposób niezależny od konkretnego systemu i jego konfiguracji. Jeśli jednak spróbujemy tę wiedzę wykorzystać we własnej aplikacji napisanej na przykład:w Javie, napotkamy zasadniczy problem. Otóż okazuje się, że parsery XML domyślnie przetwarzają deklaracje zawierające identyfikatory publiczne dokładnie tak samo, jak deklaracje tylko z identyfikatorami systemowymi, tzn. poszukują encji w ich fizycznych lokalizacjach. Pracowicie przez nas analizowany problem przenośności dokumentów jest więc domyślnie nierozwiązany! Na szczęście użycie plików catalog w procesie parsowania dokumentów XML wcale nie jest trudne. Trzeba w tym celu jedynie odpowiednio dostosować parser XML. Każdy parser SAX udostępnia interfejs EntityResolver, który umożliwia definiowanie własnego sposobu lokalizowania encji zewnętrznych. Dla wielu języków programowania (na przykład Java, C++, VisualBasic) stworzono gotowe implementacje bibliotek umożliwiających wykorzystanie plików catalog. Biblioteki te zawierają domyślne implementacje interfejsu EntityResolver, obliczające fizyczne lokalizacje plików na podstawie odwzorowań przeczytanych w pliku catalog. W szczególności można w ten sposób dostosować każdy parser XML dla Javy, implementujący interfejsy JAXP. Przyjrzyjmy się, jak to zrobić korzystając z darmowej biblioteki catalog.jar autorstwa firmy Arbortext. Listing 5 przedstawia sposób dodania do parsera entityResolverakorzystającego z plików catalog. Pliki te zostaną odczytane podczas wykonywania metody loadSystemCatalogs() z lokalizacji określonych we własności systemowej xml.catalog.files, zawierającej listę ścieżek do plików. Zauważmy, że analizę plików catalog wystarczy wykonać tylko raz, by przeczytane odwzorowania między identyfikatorami publicznymi a systemowymi móc później wielokrotnie wykorzystywać w procesie parsowania. Czynnością powtarzalną, którą musimy wykonać dla każdego parsera XML w celu jego dostosowania, jest ustawienie odpowiedniego entityResolver-a. Aby jeszcze bardziej uprościć kod aplikacji korzystającej z parsera, można stworzyć własne implementacje interfejsów JAXP SAXParserFactory oraz DocumentBuilderFactory, które będą tworzyć parser SAX lub DOM z preinstalowanym Catalog-EntityResolver-em (Listingi 6 i 7). Jeśli używamy klasy Transformer, korzystanie z własnych SAXParserFactory i DocumentBuilderFactory staje się wręcz koniecznością, ponieważ nie mamy wtedy możliwości zmiany EntityResolvera używanego do parsowania przetwarzanych dokumentów.
Listing 6. Faktoria parserów SAX z wbudowaną obsługą plików catalog
public class CatalogSAXParserFactory
extends SAXParserFactoryImpl {
public static CatalogEntityResolver cer = null;
static {
try {
cer = new CatalogEntityResolver();
Catalog myCatalog = new Catalog();
myCatalog.loadSystemCatalogs();
cer.setCatalog(myCatalog);
} catch (Exception e) {
e.printStackTrace();
}
}
public SAXParser newSAXParser()
throws ParserConfigurationException {
SAXParser sp = null;
try {
sp = super.newSAXParser();
sp.getXMLReader().setEntityResolver(cer);
}
catch (SAXException e) {
e.printStackTrace();
}
return sp;
}
public static CatalogEntityResolver getResolver() {
return cer;
}
}
Pliki catalog a aplikacje
Wiele profesjonalnych aplikacji wykorzystujących XML posiada wbudowaną obsługę plików catalog. Dotyczy to szczególnie programów, które w czasach przed-XML-owych funkcjonowały na rynku jako oprogramowanie SGML-owe i zostały dostosowane do obsługi XML-a. Na przykład profesjonalne edytory Epic firmy Arbortext oraz XMetaL firmy Corel potrafią interpretować pliki catalog zgodne z tradycyjną składnią. Trzeci wiodący na rynku edytor XMLSPY firmy Altova potrafi natomiast korzystać z plików catalog w formacie XML.
Listing 7. Faktoria parserów DOM z wbudowaną obsługą plików catalog
public class CatalogDocumentBuilderFactory
extends DocumentBuilderFactoryImpl {
public DocumentBuilder newDocumentBuilder()
throws ParserConfigurationException {
DocumentBuilder db = null;
db = super.newDocumentBuilder();
db.setEntityResolver(
CatalogSAXParserFactory.getResolver());
return db;
}
}
Świetlana przyszłość?
Zarówno identyfikatory publiczne, jak i pliki catalog służące do ich odwzorowywania na fizyczne lokalizacje encji, są konstrukcjami przejętymi z technologii SGML. Jeśli korzystamy z XML DTD, to jest to właściwie jedyna standardowa metoda uniezależnienia się od fizycznego położenia plików w systemie. Rozwój standardów związanych z XML-em a szczególnie powstanie i upowszechnienie XML Schema, zaowocował pojawieniem się nowego mechanizmu, który uzupełnia funkcjonalność plików catalog, a niekiedy je zastępuje. Mowa o przestrzeniach nazw (ang. namespaces). Elementy i atrybuty dokumentu XML zaczynamy więc umieszczać w przestrzeniach nazw. Same przestrzenie nazw deklarujemy – idąc z duchem czasu – przy pomocy identyfikatorów URI, na przykład: <html xmlns=”http://www.w3.org/1999/xhtml”> </html> Identyfikator przestrzeni nazw – podobnie jak identyfikator publiczny – ma za zadanie jednoznacznie identyfikować przestrzeń nazw i odróżniać ją od innych przestrzeni. Nie mówi jednak nic o fizycznym położeniu schematu XML Schema, który definiuje zawartość przestrzeni nazw. Fakt użycia identyfikatora URI ma znaczenie symboliczne, a sam identyfikator jest traktowany wyłącznie jako ciąg znaków i wcale nie musi wskazywać żadnego fizycznego zasobu. Pozostaje więc nadal miejsce dla stosowania plików catalog. Coraz częściej spotyka się jednak rozwiązania oparte wyłącznie na identyfikatorach przestrzeni nazw. Wykorzystują one fakt, że sam schemat XML Schema może zawierać (w atrybucie targetNamespace) deklarację przestrzeni nazw, w której znajdują się zdefiniowane w tym schemacie struktury, na przykład: <schema targetNamespace=”http://www.w3.org/1999/xhtml” xmlns=”http://www.w3.org/2000/10/XMLSchema” xmlns:xhtml=”http://www.w3.org/1999/xhtml”> </schema> Jeśli więc podczas konfiguracji zasilimy aplikację zbiorem schematów zawierających identyfikatory przestrzeni nazw, to może ona automatycznie zapamiętać odwzorowanie tych identyfikatorów na fizyczne położenie schematów (czyli zbudować własną strukturę funkcjonalnie odpowiadającą plikowi catalog). Dzięki temu, przetwarzając konkretny dokument zawierający deklarację przestrzeni nazw, aplikacja będzie mogła odnaleźć odpowiedni dla niej schemat. Mechanizm taki funkcjonuje między innymi w rozwiązaniu do edycji dokumentów XML wchodzącym w skład edytora Microsoft Office Word 2003. Identyfikatory publiczne i pliki catalog nie umrą jednak szybko śmiercią naturalną, tak jak nie umarły DTD, choć wielu proroków to przewidywało. Wciąż warto je stosować jako proste, eleganckie i sprawdzone od dziesięcioleci rozwiązanie.
Literatura
- Entity Management, OASIS Technical Resolution 9401:1997, http://www.oasis-open.org/specs/a401.htm
- XML Catalogs Committee Specification, http://www.oasis-open.org/committees/entity/spec-2001-08-06.html
- Arbortext, If You Can Name It, You Can Claim It!, http://www.arbortext.com/html/issue_three.html
- David C. Peterson, Formal Public Identifiers, http://www.oasis-open.org/cover/petersonFPI-TAG7030101.html
O autorach
Andrzej Dmoch jest ekspertem w dziedzinie XML-a, współpracującym z firmą empolis Polska.
Kontakt z autorem: andrzej.dmoch@bigfoot.com
Szymon Zioło pracuje na stanowisku manager w firmie empolis Polska. Zajmuje się projektowaniem systemów zarządzania dokumentami wykorzystujących technologie SGML/XML oraz kieruje ich wdrożeniami. Jest wykładowcą na Wydziale Matematyki, Informatyki i Mechaniki Uniwersytetu Warszawskiego, założycielem grupy dyskusyjnej pl.comp.xml i popularyzatorem technologii XML.
Kontakt z autorem: szz@empolis.pl





















Zostaw odpowiedź
Musisz być zalogowany aby publikować komentarz.