D. Konstruowanie modułów DTD

Zawartość

Ten dodatek ma charakter normatywny.

Moduły XHTML są implementowane jako fragmenty DTD. Gdy fragmenty te są łączone w określony sposób (opisany w dodatku Opracowywanie DTD ze zdefiniowanymi i rozszerzonymi modułami), wynikowe DTD reprezentuje kompletny typ dokumentu. Ta reprezentacja może być wtedy użyta do walidacji poszczególnych egzemplarzy typu dokumentu.

Rolę klucza, według którego następuje łączenie tych fragmentów w zrozumiały DTD, pełnią reguły używane do definiowania tych fragmentów. Reguły te zdefiniowane są w tym rozdziale. Gdy są one spełnione, autorzy DTD mogą być pewni, że ich moduły będą bez przeszkód wzajemnie oddziaływać z innymi modułami kompatybilnymi z XHTML.

Moduły stosujące się do tych reguł, by mogły być określane mianem modułów rodziny XHTML, muszą także spełniać wymagania zgodności ze standardem zdefiniowane w rozdziale Zgodność ze standardem modułów rodziny XHTML.

D.1. Nazywanie encji parametrycznych

Niniejsza specyfikacja dokonuje klasyfikacji encji parametrycznych na siedem kategorii i nazywa je w sposób konsekwentny, używając następujących przyrostków:

.mod
encje parametryczne posiadają przyrostek .mod, gdy są używane do reprezentowania modułu DTD (zestawu elementów, atrybutów, encji parametrycznych, itd.). W tej specyfikacji każdy moduł jest niepodzielną jednostką i może być przedstawiany jako encja w osobnym pliku.
.module
encje parametryczne posiadają przyrostek .module, gdy są używane do kontroli włączania modułu DTD za pomocą zawartego w nich słowa kluczowego sekcji warunkowej — INCLUDE albo IGNORE.
.qname
encje parametryczne posiadają przyrostek .qname, gdy są używane do reprezentowania nazwy kwalifikowanej elementu. Więcej informacji na temat nazw kwalifikowanych znajdziesz w podrozdziale Definiowanie przestrzeni nazw modułu.
.content
encje parametryczne posiadają przyrostek .content, gdy są używane do reprezentowania modelu zawartości typu elementu.
.class
encje parametryczne posiadają przyrostek .class, gdy są używane do reprezentowania elementów tej samej klasy.
.mix
encje parametryczne posiadają przyrostek .mix, gdy są używane do reprezentowania zbioru typów elementów z różnych klas.
.attrib
encje parametryczne posiadają przyrostek .attrib, gdy są używane do reprezentowania grupy leksemów, które reprezentują jedną lub więcej kompletnych specyfikacji atrybutu w obrębie deklaracji ATTLIST.

Na przykład w HTML 4 encja parametryczna %block; reprezentuje różnorodne zestawy typów elementów, z których wszystkie są elementami poziomu blokowego. W tej specyfikacji odpowiednia encja parametryczna to %Block.mix;.

Definiując encje parametryczne w ramach zdefiniowanych tutaj klas, moduły powinny określić zakres nazw encji poprzez użycie unikatowych przedrostków. Na przykład model zawartości dla elementu myelement w module mymodule powinien być nazwany MYMODULE.myelement.content. Możliwe są też inne schematy. Bez względu na użyty schemat, autorzy modułów powinni starać się osiągnąć pewność, że nazwy zdefiniowanych przez nich encji parametrycznych są unikatowe i w ten sposób nie kolidują z innymi encjami parametrycznymi, a metody interfejsu dla modułu są oczywiste dla użytkownika.

D.2. Definiowanie przestrzeni nazw modułu

XHTML wymaga, by elementy i atrybuty zadeklarowane w module istniały wewnątrz zdefiniowanej przestrzeni nazw XML [XMLNAMES]. Identyfikatorem takiej przestrzeni nazw jest dowolny URI. Gdy moduł jest implementowany przy użyciu DTD XML, XHTML wymaga, by moduł deklarował przestrzeń nazw w specjalny sposób. Służy to umożliwieniu dokonania wyboru podczas parsowania / walidacji dokumentu, użycia przedrostków przestrzeni nazw oraz przedrostka stosowanego do identyfikowania elementów i atrybutów z takiego modułu.

Jeśli twórcy treści chcą opracowywać dokumenty w oparciu o hybrydowe typy dokumentów, mogą zdecydować się na używanie przedrostków przestrzeni nazw XML w elementach z przestrzeni nazw XHTML, w elementach z innej przestrzeni nazw lub i w jednych, i w drugich. By mieć pewność, że takie dokumenty są zgodne z XHTML i wstecznie kompatybilne z narzędziami nierozpoznającymi przestrzeni nazw, W3C zaleca, by twórcy treści nie używali przedrostków przestrzeni nazw XML w elementach z przestrzeni nazw XHTML. Jeśli twórcy treści są zainteresowani tym, by zawartość ich dokumentów była przetwarzana przez procesory nierozpoznające przestrzeni nazw, W3C zaleca także, by elementy w przestrzeniach nazw innych niż XHTML były określane przy użyciu przedrostka przestrzeni nazw XML, a nie w oparciu o domyślne mechanizmy przestrzeni nazw XML.

Od każdego modułu zgodnego z XHTML zaimplementowanego jako DTD XML wymaga się, by miał zdefiniowany domyślny przedrostek przestrzeni nazw XML, metodę zamiany tego przedrostka wewnątrz egzemplarza dokumentu oraz wskazaną sekcję włączającą przetwarzanie tego przedrostka.

Weź pod uwagę, że jeśli moduły są ze sobą powiązane, jest dopuszczalnym i oczekiwanym, by były częścią tej samej przestrzeni nazw. Na przykład wszystkie moduły XHTML są częścią tej samej przestrzeni nazw.

D.2.1. Podmoduł nazw kwalifikowanych

Na początku musisz zdefiniować podmoduł nazw kwalifikowanych (podmoduł to po prostu oddzielna encja plikowa mogąca w odpowiednim punkcie być włączona do ostatecznego DTD). Podmoduł nazw kwalifikowanych tworzy się według następujących kroków (w których łańcuch MODULE jest zastępowany odpowiednim dla nowego modułu łańcuchem):

  1. Zdefiniuj encję parametryczną MODULE.przedrostek, która będzie wskazywała czy elementy w module są używane z przedrostkami przestrzeni nazw XML, czy nie. Domyślną wartością tej encji parametrycznej powinno być "%NS.prefixed;". Zasady ogólne XHTML definiują domyślną wartość encji parametrycznej NS.prefixed jako IGNORE. Encja ta może być użyta w egzemplarzu dokumentu do dołączania przedrostków dla wszystkich włączonych przestrzeni nazw (łącznie z tymi z modułów XHTML).
  2. Zdefiniuj encję parametryczną MODULE.xmlns zawierającą identyfikator przestrzeni nazw dla tego modułu.
  3. Zdefiniuj encję parametryczną MODULE.prefix zawierającą łańcuch domyślnego przedrostka, używany, gdy uaktywnione jest dołączanie przedrostków.
  4. Zdefiniuj encję parametryczną MODULE.pfx, której wartość jest równa "%MODULE.prefix;:", gdy uaktywnione jest dołączanie przedrostków, a "" w przeciwnym wypadku.
  5. Zdefiniuj encję parametryczną MODULE.xmlns.extra.attrib zawierającą deklarację każdego atrybutu przestrzeni nazw XML dla przestrzeni nazw, do których odwołuje się ten moduł (np. xmlns:xlink). Gdy wartość %MODULE.prefixed jest równa INCLUDE, atrybut ten powinien zawierać także deklarację xmlns:%MODULE.prefix;.
  6. Zdefiniuj encję parametryczną XHTML.xmlns.extra.attrib jako MODULE.xmlns.extra.attrib. Jest to zwykle nadpisywane przez plik sterownika typu dokumentu, ale jeśliby się tak nie stało, ta definicja zajmie miejsce jako domyślna.
  7. Dla każdego z elementów zdefiniowanych przez ten moduł utwórz encję parametryczną postaci "MODULE.NAME.qname" przechowującą jego nazwę kwalifikowaną. Encja ta musi mieć wartość "%MODULE.pfx;NAME". Wtedy wartością sparsowana będzie "PREFIX:NAME", gdy uaktywnione jest dołączanie przedrostków, a "NAME" w przeciwnym wypadku.

    Jeśli moduł dodaje atrybuty do elementów zdefiniowanych w modułach niepodzielających przestrzeni nazw tego modułu, zadeklaruj te atrybuty, by używały przedrostka %MODULE.pfx. Na przykład:

    <ENTITY % MODULE.img.myattr.qname "%MODULE.pfx;myattr" >
    

Poniżej widnieje przykład podmodułu nazw kwalifikowanych dla hipotetycznego modułu Inventory (‘spis towarów’):

<!-- ...................................................................... -->
<!-- Inventory Qname Module ................................................... -->
<!-- plik: inventory-qname-1.mod

     PUBLIC "-//MY COMPANY//ELEMENTS XHTML Inventory Qnames 1.0//EN"
     SYSTEM "http://www.example.com/DTDs/inventory-qname-1.mod"

     xmlns:inventory="http://www.example.com/xmlns/inventory"
     ...................................................................... -->

<!-- Zadeklaruj domyślną wartość przedrostka dla elementów tego modułu -->
<!-- Weź pod uwagę, że NS.prefixed zostanie uchylona przez zasady ogólne XHTML
     lub przez egzemplarz dokumentu. -->
<!ENTITY % NS.prefixed "IGNORE" >
<!ENTITY % Inventory.prefixed "%NS.prefixed;" >

<!-- Zadeklaruj rzeczywistą przestrzeń nazw tego modułu -->
<!ENTITY % Inventory.xmlns "http://www.example.com/xmlns/inventory" >

<!-- Zadeklaruj domyślny przedrostek dla tego modułu -->
<!ENTITY % Inventory.prefix "inventory" >

<!-- Zadeklaruj przedrostek dla tego modułu -->
<![%Inventory.prefixed;[
<!ENTITY % Inventory.pfx "%Inventory.prefix;:" >
]]>
<!ENTITY % Inventory.pfx "" >

<!-- Zadeklaruj atrybut xmlns dla tego modułu -->
<![%Inventory.prefixed;[
<!ENTITY % Inventory.xmlns.extra.attrib
    "xmlns:%Inventory.prefix;   %URI.datatype;  #FIXED  '%Inventory.xmlns;'" >
]]>
<!ENTITY % Inventory.xmlns.extra.attrib "" >

<!-- Zadeklaruj dodatkową przestrzeń nazw, która powinna być zawarta w
     elementach XHTML -->
<!ENTITY % XHTML.xmlns.extra.attrib
    %Inventory.xmlns.extra.attrib; >

<!-- Teraz zadeklaruj nazwy kwalifikowane dla wszystkich elementów w module -->
<!ENTITY % Inventory.shelf.qname "%Inventory.pfx;shelf" >
<!ENTITY % Inventory.item.qname "%Inventory.pfx;item" >
<!ENTITY % Inventory.desc.qname "%Inventory.pfx;desc" >
<!ENTITY % Inventory.sku.qname "%Inventory.pfx;sku" >
<!ENTITY % Inventory.price.qname "%Inventory.pfx;price" >

D.2.2. Podmoduł(y) deklaracji

Następnie musisz zdefiniować jeden lub więcej „podmodułów deklaracji”. Zadaniem tych encji plikowych jest zadeklarowanie elementów i wykazów atrybutów DTD XML. Moduł deklaracji XHTML powinien być skonstruowany przy użyciu następujących kroków:

  1. Zdefiniuj encję parametryczną w celu używania jej wewnątrz ATTLIST każdego zadeklarowanego elementu. Ta encja parametryczna powinna zawierać %NS.decl.attrib;, gdy %MODULE.prefixed; ma wartość INCLUDE, a %NS.decl.attrib; plus "xmlns %URI.datatype; #FIXED '%MODULE.xmlns;'", gdy %MODULE.prefixed; ma wartość IGNORE.
  2. Zadeklaruj wszystkie elementy i atrybuty dla tego modułu. Wewnątrz każdej ATTLIST dla elementu zawrzyj encję parametryczną zdefiniowaną powyżej, by wszystkie wymagane atrybuty xmlns były dostępne w każdym elemencie w module.
  3. Jeśli moduł dodaje atrybuty do elementów zdefiniowanych w modułach niepodzielających przestrzeni nazw tego modułu, zadeklaruj te atrybuty, by używały przedrostka %MODULE.pfx. Na przykład:

    <ENTITY % MODULE.img.myattr.qname "%MODULE.pfx;myattr" >
    <!ATTLIST %img.qname;
          %MODULE.img.myattr.qname;    CDATA          #IMPLIED
    >
    

    Spowoduje to dodanie atrybutu do elementu img z modułu Image, ale nazwą atrybutu będzie nazwa kwalifikowana, z przedrostkiem, jeśli przedrostki są wybrane dla egzemplarza dokumentu. Nastąpi też dodanie atrybutu xmlns:MODULE_PREFIX do wykazu atrybutów elementu img, dzięki czemu parsery nierozpoznające przestrzeni nazw XML będą wiedziały jak rozwiązać przestrzeń nazw opartą na jego przedrostku.

Poniższy przykład przedstawia podmoduł deklaracji dla hipotetycznego modułu Inventory (‘spis towarów’).

<!-- ...................................................................... -->
<!-- Inventory Elements Module ................................................... -->
<!-- plik: inventory-1.mod

     PUBLIC "-//MY COMPANY//ELEMENTS XHTML Inventory Elements 1.0//EN"
     SYSTEM "http://www.example.com/DTDs/inventory-1.mod"

     xmlns:inventory="http://www.example.com/xmlns/inventory"
     ...................................................................... -->

<!-- Moduł Inventory

     shelf      (‘półka’)
       item     (‘pozycja’)
         sku    (SKU = stock-keeping unit — ‘unikatowy kod towaru’)
         desc   (description — ‘opis’)
         price  (‘cena’)

     Ten moduł definiuje podstawową strukturę pozycji spisu towarów
-->

<!-- Zdefiniuj atrybuty globalnej przestrzeni nazw -->
<![%Inventory.prefixed;[
<!ENTITY % Inventory.xmlns.attrib
    "%NS.decl.attrib;"
>
]]>
<!ENTITY % Inventory.xmlns.attrib
     "xmlns %URI.datatype;  #FIXED '%Inventory.xmlns;'"
>

<!-- Zdefiniuj zestaw atrybutów wspólnych dla wszystkich elementów modułu -->
<!ENTITY % Inventory.Common.attrib
         "%Inventory.xmlns.attrib;
      id               ID                   #IMPLIED
>

<!-- Zdefiniuj elementy i atrybuty modułu -->
<!ELEMENT %Inventory.shelf.qname;
     ( %Inventory.item.qname; )* >
<!ATTLIST %Inventory.shelf.qname;
     location   CDATA   #IMPLIED
     %Inventory.Common.attrib;
>
<!ELEMENT %Inventory.item.qname;
     ( %Inventory.desc.qname;, %Inventory.sku.qname;, %Inventory.price.qname;) >
<!ATTLIST %Inventory.item.qname;
     location   CDATA   #IMPLIED
     %Inventory.Common.attrib;
>

<!ELEMENT %Inventory.desc.qname; ( #PCDATA ) >
<!ATTLIST %Inventory.desc.qname;
     %Inventory.Common.attrib;
>

<!ELEMENT %Inventory.sku.qname; ( #PCDATA ) >
<!ATTLIST %Inventory.sku.qname;
     %Inventory.Common.attrib;
>

<!ELEMENT %Inventory.price.qname; ( #PCDATA ) >
<!ATTLIST %Inventory.price.qname;
     %Inventory.Common.attrib;
>

<!-- koniec pliku inventory-1.mod -->

D.2.3. Używanie modułu jako samodzielnego DTD

Czasem jest pożądane, by móc używać modułu XHTML także jako samodzielne DTD. Dobrym tego przykładem jest nasz powyższy moduł Inventory. Obiekty te muszą móc się zagnieżdżać w dokumencie XHTML i muszą być dostępne jako odrębne dokumenty wydzielone z bazy danych (na przykład). Najłatwiejszym sposobem osiągnięcia tego jest zdefiniowanie pliku DTD rozwijającego składniki twojego modułu. Takie DTD mogłoby mieć następującą strukturę:

  1. Włącz moduł XHTML Datatypes (twój moduł nazw kwalifikowanych prawdopodobnie używa niektóre z tych typów danych — na pewno używa typ danych URI dla atrybutu xmlns).
  2. Włącz moduł nazw kwalifikowanych do twojego modułu.
  3. Zdefiniuj encję parametryczną NS.decl.attrib jako %MODULE.xmlns.extra.attrib;.
  4. Włącz moduł(y) deklaracji do twojego modułu.

Przykład obrazujący te działania dla naszego modułu Inventory jest przedstawiony poniżej:

<!-- ...................................................................... -->
<!-- Inventory Elements DTD ............................................... -->
<!-- plik: inventory-1.dtd

     PUBLIC "-//MY COMPANY//DTD XHTML Inventory 1.0//EN"
     SYSTEM "http://www.example.com/DTDs/inventory-1.dtd"

     xmlns:inventory="http://www.example.com/xmlns/inventory"
     ...................................................................... -->

<!-- Moduł Inventory

     shelf
       item
         sku
         desc
         price

     Ten moduł definiuje podstawową strukturę pozycji spisu towarów
-->

<!-- Wprowadź typy danych -->
<!ENTITY % xhtml-datatypes.mod
         PUBLIC "-//W3C//ENTITIES XHTML Datatypes 1.0//EN"
         "http://www.w3.org/TR/xhtml-modularization/DTD/xhtml-datatypes-1.mod" >
%xhtml-datatypes.mod;

<!-- Wprowadź nazwy kwalifikowane -->
<!ENTITY % Inventory-qname.mod SYSTEM "inventory-qname-1.mod" >
%Inventory-qname.mod;

<!ENTITY % NS.decl.attrib "%Inventory.xmlns.extra.attrib;">

<!ENTITY % Inventory.mod SYSTEM "inventory-1.mod" >
%Inventory.mod;

<!-- koniec pliku inventory-1.dtd -->

Do tego DTD mogą się później odwoływać dokumenty, które używają tylko elementów z twojego modułu:

<!DOCTYPE shelf SYSTEM "inventory-1.dtd">
<shelf xmlns="http://www.example.com/xmlns/inventory">
    <item>
        <desc>
          to jest opis
        </desc>
        <sku>
          to jest unikatowy kod towaru
        </sku>
        <price>
          to jest cena
        </price>
    </item>
</shelf>

Ta metoda zezwala na definiowanie elementów i atrybutów zawartych wewnątrz swojej własnej przestrzeni nazw. Pozwala też, by twórcy treści używali domyślnego przedrostka dla tych elementów i atrybutów:

<!DOCTYPE inventory:shelf SYSTEM "inventory-1.dtd" [
    <!ENTITY % Inventory.prefixed "INCLUDE">
]>
<inventory:shelf xmlns:inventory="http://www.example.com/xmlns/inventory">
    <inventory:item>
        <inventory:desc>
          to jest opis
        </inventory:desc>
        <inventory:sku>
          to jest unikatowy kod towaru
        </inventory:sku>
        <inventory:price>
          to jest cena
        </inventory:price>
    </inventory:item>
</inventory:shelf>

Egzemplarz dokumentu może używać innego przedrostka przestrzeni nazw XML dzięki powtórnemu zadeklarowaniu go w wewnętrznym podzbiorze nagłówka DOCTYPE:

<!DOCTYPE i:shelf SYSTEM "inventory-1.dtd" [
    <!ENTITY % Inventory.prefixed "INCLUDE">
    <!ENTITY % Inventory.prefix "i">
]>
<i:shelf xmlns:i="http://www.example.com/xmlns/inventory">
    <i:item>
        <i:desc>
          to jest opis
        </i:desc>
        <i:sku>
          to jest unikatowy kod towaru
        </i:sku>
        <i:price>
          to jest cena
        </i:price>
    </i:item>
</i:shelf>

D.2.4. Specyficzne własności przestrzeni nazw

Zaprezentowane tu podejście pozwala na definiowanie języków znaczników zgodnych z XML i przestrzeniami nazw XML, jednak niektóre możliwości zdefiniowane w specyfikacji przestrzeni nazw XML nie są obsługiwane:

  1. Przestrzenie nazw XML zezwalają na powtórną deklarację atrybutu xmlns dla przestrzeni nazw w dowolnym punkcie drzewa. Zezwala też, by poprzez redeklarację przełączać pomiędzy użyciem domyślnym przestrzeni nazw (bez przedrostka) a użyciem z przedrostkiem, a także na zmianę przedrostka. Metoda zdefiniowana w tym dokumencie nie pozwala na to. W całym egzemplarzu dokumentu dana przestrzeń nazw musi używać tego samego przedrostka albo musi być użyta w domyślnym zakresie.

  2. Gdy przestrzeń nazw XML używana jest w domyślny sposób (bez przedrostka), dopuszczalne jest informowanie parserów o przestrzeni nazw elementu przy pomocy DTD dokumentu. Jednakże dopóki procesory nierozpoznające przestrzeni nazw nie są zobligowane do przyłączania DTD podczas analizowania dokumentu, twórcy treści powinni deklarować przestrzeń nazw XML elementu zawsze, gdy przestrzeń nazw się zmienia:

    ...
    <p>
       <myelement xmlns="..." />
    </p>
    

Strona główna Ostatnia modyfikacja: 17 sierpnia 2005