Definicja typu dokumentu - Document type definition

Definicja typu dokumentu ( DTD ) to zestaw znaczników deklaracji , które definiują typ dokumentu dla SGML -family języka znaczników ( GML , SGML , XML , HTML ).

DTD definiuje prawidłowe bloki konstrukcyjne dokumentu XML. Definiuje strukturę dokumentu z listą zwalidowanych elementów i atrybutów. DTD można zadeklarować w tekście w dokumencie XML lub jako odwołanie zewnętrzne.

XML używa podzbioru SGML DTD.

Od 2009 roku nowsze języki schematów obsługujące przestrzeń nazw XML (takie jak W3C XML Schema i ISO RELAX NG ) w dużej mierze zastąpiły DTD. Wersja DTD uwzględniająca przestrzeń nazw jest opracowywana jako część 9 ISO DSDL . DTD utrzymują się w aplikacjach, które wymagają specjalnych znaków publikowania, takich jak XML i HTML Character Entity References , które wywodzą się z większych zestawów zdefiniowanych w ramach standardu ISO SGML .

Powiązanie DTD z dokumentami

DTD jest kojarzone z dokumentem XML lub SGML za pomocą deklaracji typu dokumentu (DOCTYPE). DOCTYPE pojawia się we fragmencie składniowym doctypedecl w pobliżu początku dokumentu XML. Deklaracja ustala, że ​​dokument jest instancją typu zdefiniowanego przez DTD, do którego się odwołuje.

DOCTYPE składają dwa rodzaje deklaracji:

  • opcjonalny podzbiór zewnętrzny
  • opcjonalny podzbiór wewnętrzny .

Deklaracje w wewnętrznym podzbiorze stanowią część DOCTYPE w samym dokumencie. Deklaracje w zewnętrznym podzbiorze znajdują się w osobnym pliku tekstowym. Do zewnętrznego podzbioru można się odwoływać poprzez identyfikator publiczny i/lub identyfikator systemowy . Programy do czytania dokumentów mogą nie być wymagane do odczytywania podzbioru zewnętrznego.

Każdy ważny dokument SGML lub XML, który odwołuje się do zewnętrznego podzbioru w swoim DTD lub którego treść zawiera odniesienia do przeanalizowanych zewnętrznych podmiotów zadeklarowanych w jego DTD (w tym tych zadeklarowanych w jego wewnętrznym podzbiorze ), może być tylko częściowo przeanalizowany, ale nie może być w pełni zweryfikowany przez walidację Parsery SGML lub XML w trybie autonomicznym (oznacza to, że te parsery walidujące nie próbują pobierać tych zewnętrznych jednostek, a ich tekst zastępczy jest niedostępny).

Jednak takie dokumenty są jeszcze w pełni parsable w non trybie -standalone walidacji parserami, który sygnalizuje błąd, jeśli nie można zlokalizować te podmioty zewnętrzne z ich określonym identyfikatorem publicznym (FPI) lub identyfikator systemu (URI), albo są niedostępne . (Notacje zadeklarowane w DTD odnoszą się również do zewnętrznych jednostek, ale te nieprzeanalizowane jednostki nie są potrzebne do walidacji dokumentów w trybie autonomicznym tych parserów: walidacja wszystkich zewnętrznych encji, do których odwołują się notacje, jest pozostawiona aplikacji przy użyciu SGML lub parser XML). Niewalidujący parser może ostatecznie próbować zlokalizować te podmioty zewnętrzne w non trybie -standalone (poprzez częściowe interpretacji DTD tylko do rozwiązywania zgłoszonych podmiotów parsable), ale nie potwierdzić model zawartości tych dokumentów.

Przykłady

Poniższy przykład DOCTYPE zawiera zarówno identyfikatory publiczne, jak i systemowe:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

Wszystkie dokumenty HTML 4.01 są zgodne z jednym z trzech DTD SGML. Publiczne identyfikatory tych DTD są stałe i są następujące:

Identyfikatory systemowe tych DTD, jeśli są obecne w DOCTYPE, są odwołaniami URI . Identyfikator systemu zwykle wskazuje na określony zestaw deklaracji w możliwej do rozwiązania lokalizacji. SGML umożliwia mapowanie identyfikatorów publicznych na identyfikatory systemowe w katalogach, które są opcjonalnie dostępne dla programów rozpoznawania URI używanych przez oprogramowanie do analizowania dokumentów .

Ten DOCTYPE może pojawić się tylko po opcjonalnej deklaracji XML i przed treścią dokumentu, jeśli składnia dokumentu jest zgodna z XML. Obejmuje to dokumenty XHTML :

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<!-- the XHTML document body starts here-->
<html xmlns="http://www.w3.org/1999/xhtml">
 ...
</html>

Dodatkowy podzbiór wewnętrzny może być również dostarczony po podzbiorze zewnętrznym:

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd" [
  <!-- an internal subset can be embedded here -->
]>
<!-- the XHTML document body starts here-->
<html xmlns="http://www.w3.org/1999/xhtml">
 ...
</html>

Alternatywnie można podać tylko podzbiór wewnętrzny:

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE html [
  <!-- an internal subset can be embedded here -->
]>
<!-- the XHTML document body starts here-->
<html xmlns="http://www.w3.org/1999/xhtml">
 ...
</html>

Wreszcie definicja typu dokumentu może w ogóle nie zawierać podzbioru; w takim przypadku określa po prostu, że dokument ma jeden element najwyższego poziomu (jest to niejawne wymaganie dla wszystkich poprawnych dokumentów XML i HTML, ale nie dla fragmentów dokumentów lub wszystkich dokumentów SGML, których elementy najwyższego poziomu mogą być różne z domniemanego elementu głównego) i wskazuje nazwę typu elementu głównego:

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE html>
<!-- the XHTML document body starts here-->
<html xmlns="http://www.w3.org/1999/xhtml">
 ...
</html>

Deklaracje znaczników

DTD opisują strukturę klasy dokumentów poprzez deklaracje elementów i listy atrybutów. Deklaracje elementów nazywają dozwolony zestaw elementów w dokumencie i określają, czy i jak zadeklarowane elementy i ciągi danych znakowych mogą być zawarte w każdym elemencie. Deklaracje listy atrybutów nazywają dozwolony zestaw atrybutów dla każdego zadeklarowanego elementu, w tym typ każdej wartości atrybutu, jeśli nie jest to jawny zestaw prawidłowych wartości.

Deklaracje znaczników DTD deklarują, które typy elementów , listy atrybutów , encje i notacje są dozwolone w strukturze odpowiedniej klasy dokumentów XML.

Deklaracje typu elementu

Deklaracja typu elementu definiuje element i jego możliwą zawartość. Prawidłowy dokument XML zawiera tylko elementy zdefiniowane w DTD.

Różne słowa kluczowe i znaki określają zawartość elementu:

  • EMPTY do określenia, że ​​zdefiniowany element nie zezwala na treść, tj. nie może mieć żadnych elementów potomnych, nawet elementów tekstowych (jeśli są spacje, są one ignorowane);
  • ANY o określenie, że definiowany element dopuszcza dowolną treść bez ograniczeń, tj. może mieć dowolną liczbę (w tym brak) i rodzaj elementów potomnych (w tym elementy tekstowe);
  • lub wyrażenie określające tylko elementy dozwolone jako bezpośrednie dzieci w treści zdefiniowanego elementu; ta treść może być:
    • zawartość mieszanego , co oznacza, że zawartość może zawierać co najmniej jeden element tekstu i zero lub więcej nazw elementów, ale ich kolejności i liczby zdarzeń nie może być ograniczony; to może być:
      • ( #PCDATA ): historycznie oznacza przeanalizowane dane znakowe , oznacza to, że tylko jeden element tekstowy jest dozwolony w treści (nie jest dozwolony kwantyfikator);
      • ( #PCDATA | ''element name'' | ... )*: ograniczony wybór (na wyłącznej liście w nawiasach i oddzielonych " |" znakami kreski pionowej i zakończony wymaganym *kwantyfikatorem " ") dwóch lub więcej elementów potomnych (w tym tylko elementy tekstowe lub określone elementy nazwane) może być użyty w dowolnej kolejności i liczbę wystąpień w treści.
    • zawartość elementu , co oznacza, że nie może być żadnych elementów tekstowych w dzieciach elementami treści (wszystkie odstępy między elementami zakodowane dzieci są wtedy ignorowane, podobnie jak komentarze). Taka zawartość elementu jest określona jako cząstka zawartości w wariancie formy Backus-Naur bez symboli końcowych i nazw elementów jako symbole nieterminalne. Zawartość elementu składa się z:
      • cząstek zawartość może być zarówno nazwa elementu zadeklarowane w DTD, lub liście sekwencji lub listy wyboru . Po nim może występować opcjonalny kwantyfikator .
        • liście sekwencji oznacza uporządkowaną listę (określone w nawiasach i oddzielonych „ ,” charakteru przecinek) jednego lub więcej zawartość cząstek : wszystkie zawartości cząstek muszą być umieszczone kolejno za bezpośrednie dzieci w zawartości określonego elementu, przy określonym położeniu i względny porządek;
        • listy wyboru oznacza wzajemnie wykluczającą listę (podany w nawiasach i oddzielonych „ |” postać rury) dwóch lub więcej, zawartość cząstek : tylko jeden z tych zawartości cząstek mogą występować w zawartości określonego elementu w tym samym położeniu.
      • Kwantyfikator jest pojedynczym znakiem, że natychmiast następuje określony element Dotyczy ona, aby ograniczyć liczbę kolejnych wystąpień tych przedmiotów w określonym położeniu w treści elementu; może to być:
        • + do określenia, że ​​musi wystąpić jedno lub więcej wystąpień elementu — efektywna treść każdego wystąpienia może być inna;
        • * do określenia, że ​​dozwolona jest dowolna liczba (zero lub więcej) wystąpień — element jest opcjonalny, a efektywna treść każdego wystąpienia może być inna;
        • ? do określenia, że ​​nie może być więcej niż jedno wystąpienie — pozycja jest opcjonalna;
        • Jeśli nie ma kwantyfikatora, określony element musi wystąpić dokładnie jeden raz w określonej pozycji w treści elementu.

Na przykład:

<!ELEMENT html (head, body)>
<!ELEMENT p (#PCDATA | p | ul | dl | table | h1|h2|h3)*>

Deklaracje typu elementu są ignorowane przez niewalidujący SGML i XML parserami (w jakich przypadkach, wszelkie elementy są przyjmowane w dowolnej kolejności iw dowolnej liczby wystąpień w przeanalizowanej dokumentu), ale te deklaracje są nadal sprawdzane pod kątem formy i ważności.

Deklaracje listy atrybutów

Lista atrybutów określa dla danego typu elementu listę wszystkich możliwych atrybutów powiązanych z tym typem. Dla każdego możliwego atrybutu zawiera:

  • zadeklarowana nazwa atrybutu,
  • jego typ danych (lub wyliczenie jego możliwych wartości),
  • i jego wartość domyślną.

Na przykład:

<!ATTLIST img
   src    CDATA          #REQUIRED
   id     ID             #IMPLIED
   sort   CDATA          #FIXED "true"
   print  (yes | no) "yes"
>

Oto kilka typów atrybutów obsługiwanych zarówno przez SGML, jak i XML:

CDATA
ten typ oznacza znaki dane i wskazuje, że efektywna wartość atrybutu może być dowolną wartością tekstową, chyba że atrybut jest określony jako stały (komentarze w DTD mogą dalej dokumentować wartości, które są efektywnie akceptowane, ale składnia DTD nie pozwala na takie precyzyjna specyfikacja);
ID
efektywna wartość atrybutu musi być poprawnym identyfikatorem i jest używana do definiowania i zakotwiczania do bieżącego elementu celu odwołań przy użyciu tego zdefiniowanego identyfikatora (w tym jako identyfikatory fragmentów dokumentu, które mogą być określone na końcu URI po " #" znak); jest błędem, jeśli różne elementy w tym samym dokumencie definiują ten sam identyfikator; ograniczenie niepowtarzalności oznacza również, że sam identyfikator nie zawiera żadnej innej semantyki i że identyfikatory muszą być traktowane jako nieprzejrzyste w aplikacjach; XML predefiniuje również standardowy pseudoatrybut " xml:id" z tym typem, bez potrzeby jakiejkolwiek deklaracji w DTD, więc ograniczenie unikatowości dotyczy również tych zdefiniowanych identyfikatorów, gdy są one określone w dowolnym miejscu w dokumencie XML.
IDREF lub IDREFS
efektywna wartość atrybutu może być tylko prawidłowym identyfikatorem (lub oddzieloną spacjami listą takich identyfikatorów) i musi odwoływać się do unikalnego elementu zdefiniowanego w dokumencie z atrybutem zadeklarowanym z typem IDw DTD (lub unikalnym elementem zdefiniowanym w dokumencie XML z pseudoatrybutem „ xml:id”, którego efektywną wartością jest ten sam identyfikator;
NMTOKEN lub NMTOKENS
efektywna wartość atrybutu może być tylko ważnym tokenem nazwy (lub oddzieloną spacjami listą takich tokenów nazwy), ale nie jest ograniczona do unikalnego identyfikatora w dokumencie; nazwa ta może zawierać semantykę uzupełniającą i zależną od aplikacji oraz może wymagać dodatkowych ograniczeń nazewnictwa, ale jest to poza zakresem DTD;
ENTITY lub ENTITIES
efektywną wartością atrybutu może być tylko nazwa nieprzeanalizowanej encji zewnętrznej (lub oddzielona spacjami lista takich nazw), która również musi być zadeklarowana w deklaracji typu dokumentu; ten typ nie jest obsługiwany przez parsery HTML, ale jest poprawny w SGML i XML 1.0 lub 1.1 (w tym XHTML i SVG);
(''value1''|...)
efektywna wartość atrybutu może być tylko jedną z wyliczonych list (określonych w nawiasach i oddzielonych znakiem |kreski pionowej) wartości tekstowych, gdzie każda wartość w wyliczeniu jest prawdopodobnie określona w 'pojedynczym 'lub "podwójnym "cudzysłowie, jeśli nie jest prosty token nazwy;
NOTATION (''notation1''|...)
efektywna wartość atrybutu może być tylko jedną z wyliczonych list (określonych w nawiasach i oddzielonych znakiem |kreski pionowej) nazw notacji, przy czym każda nazwa notacji w wyliczeniu musi być również zadeklarowana w deklaracji typu dokumentu; ten typ nie jest obsługiwany przez parsery HTML, ale jest poprawny w SGML i XML 1.0 lub 1.1 (w tym XHTML i SVG).

Wartość domyślna może określać, czy atrybut musi wystąpić ( #REQUIRED) czy nie ( #IMPLIED), czy ma stałą wartość ( #FIXED), lub która wartość powinna być użyta jako wartość domyślna ("…") w przypadku pominięcia danego atrybutu w znaczniku XML.

Deklaracje lista atrybutów są ignorowane przez niewalidujący SGML i XML parser (przypadki, w których każdy atrybut jest przyjęte we wszystkich elementach analizowanej dokumencie), ale te deklaracje są nadal sprawdzane pod kątem sensowności i ważności.

Deklaracje podmiotu

Jednostka jest podobna do makra . Deklaracja encji przypisuje jej wartość, która jest zachowywana w całym dokumencie. Powszechnym zastosowaniem jest posiadanie nazwy bardziej rozpoznawalnej niż odniesienie do znaków numerycznych dla nieznanego znaku. Encje pomagają poprawić czytelność tekstu XML. Ogólnie rzecz biorąc, istnieją dwa typy: wewnętrzny i zewnętrzny.

  • Wewnętrzne (przeanalizowane) jednostki kojarzą nazwę z dowolną arbitralną treścią tekstową zdefiniowaną w ich deklaracji (która może znajdować się w wewnętrznym podzbiorze lub w zewnętrznym podzbiorze DTD zadeklarowanego w dokumencie). Gdy odwołanie do nazwanej encji zostanie następnie napotkane w pozostałej części dokumentu (w tym w pozostałej części DTD) i jeśli ta nazwa encji została faktycznie zdefiniowana jako encja przeanalizowana, samo odwołanie jest natychmiast zastępowane treścią tekstową zdefiniowaną w przeanalizowanej encji, a parsowanie będzie kontynuowane w tym tekście zastępczym.
    • Predefiniowane nazwane encje znakowe są podobne do encji wewnętrznych: 5 z nich jest jednak specjalnie traktowanych we wszystkich parserach SGML, HTML i XML. Te encje różnią się nieco od normalnych encji analizowanych, ponieważ gdy w dokumencie napotkane zostanie odwołanie do encji nazwanego znaku, odwołanie jest również natychmiast zastępowane treścią znaku zdefiniowaną w encji, ale parsowanie jest kontynuowane po tekście zastępczym, który jest natychmiast wstawiany dosłownie w aktualnie analizowanym tokenie (jeśli taki znak jest dozwolony w wartości tekstowej tego tokena). Dzięki temu niektóre znaki, które są potrzebne do podstawowej składni HTML lub samego XML, mogą zostać ominięte ze swojej specjalnej roli składniowej (zwłaszcza „&”, która jest zarezerwowana dla początkowych odwołań do encji, „<” lub „>”, które ograniczają znaczniki znaczników, oraz „podwójne” lub „pojedyncze” cudzysłowy, które oddzielają wartości atrybutów i definicji encji). Predefiniowane jednostki znakowe zawierają również odwołania do znaków numerycznych, które są obsługiwane w ten sam sposób i mogą być również używane do ucieczki znaków, które reprezentują, lub do ominięcia ograniczeń w repertuarze znaków obsługiwanym przez kodowanie dokumentu.
    • W podstawowych profilach dla SGML lub w dokumentach HTML deklaracja encji wewnętrznych nie jest możliwa (ponieważ zewnętrzne podzbiory DTD nie są pobierane, a wewnętrzne podzbiory DTD nie są obsługiwane w tych podstawowych profilach).
    • Zamiast tego, standardy HTML predefiniują duży zestaw kilkuset nazwanych jednostek znakowych, które nadal mogą być obsługiwane jako standardowe przeanalizowane jednostki zdefiniowane w DTD używanym przez parser.
  • Jednostki zewnętrzne odnoszą się do zewnętrznych obiektów pamięci masowej. Są one po prostu deklarowane przez unikalną nazwę w dokumencie i definiowane za pomocą publicznego identyfikatora (FPI) i/lub identyfikatora systemowego (interpretowanego jako URI ) określającego, gdzie jest źródło ich zawartości. W rzeczywistości istnieją w dwóch wariantach:
    • parsowane podmioty zewnętrzne (najczęściej zdefiniowane identyfikatorem SYSTEM wskazującym URI ich zawartości), które nie są powiązane w ich definicji z nazwaną adnotacją, w takim przypadku sprawdzanie poprawności parserów XML lub SGML pobiera ich zawartość i parsuje je tak, jakby zostały zadeklarowane jako encje wewnętrzne (obiekt zewnętrzny zawierający ich skuteczny tekst zastępczy);
    • nieprzeanalizowane zewnętrzne encje, które są zdefiniowane i powiązane z nazwą adnotacji, w takim przypadku są one traktowane jako nieprzezroczyste referencje i jako takie sygnalizowane aplikacji za pomocą parsera SGML lub XML: ich interpretacja, pobieranie i parsowanie jest pozostawione aplikacji, zgodnie z typy adnotacji, które obsługuje (zobacz następną sekcję o adnotacjach i przykłady nieprzeanalizowanych encji zewnętrznych).
    • Encje zewnętrzne nie są obsługiwane w podstawowych profilach dla SGML lub w dokumentach HTML, ale są poprawne w pełnych implementacjach SGML i XML 1.0 lub 1.1 (w tym XHTML i SVG, nawet jeśli nie są one ściśle potrzebne w tych typach dokumentów).

Przykład deklaracji encji wewnętrznych (tutaj w wewnętrznym podzbiorze DTD dokumentu SGML) to:

<!DOCTYPE sgml [
  <!ELEMENT sgml ANY>
  <!ENTITY % std       "standard SGML">
  <!ENTITY % signature " &#x2014; &author;.">
  <!ENTITY % question  "Why couldn&#x2019;t I publish my books directly in %std;?">
  <!ENTITY % author    "William Shakespeare">
]>
<sgml>&question;&signature;</sgml>

Jednostki wewnętrzne mogą być definiowane w dowolnej kolejności, o ile nie są przywoływane i analizowane w DTD lub w treści dokumentu, w kolejności ich parsowania: dopuszczalne jest umieszczenie odniesienia do wciąż niezdefiniowanej encji w treści przeanalizowanej encji, ale niedozwolone jest uwzględnienie w dowolnym innym miejscu odniesienia do nazwanej encji przed pełnym zdefiniowaniem tej encji, w tym wszystkich innych encji wewnętrznych, do których odwołuje się jej zdefiniowana zawartość (zapobiega to również cyklicznym lub rekurencyjnym definicjom encji wewnętrznych). Ten dokument jest analizowany tak, jakby był:

<!DOCTYPE sgml [
  <!ELEMENT sgml ANY>
  <!ENTITY % std       "standard SGML">
  <!ENTITY % signature " — &author;.">
  <!ENTITY % question  "Why couldn’t I publish my books directly in standard SGML?">
  <!ENTITY % author    "William Shakespeare">
]>
<sgml>Why couldn’t I publish my books directly in standard SGML? — William Shakespeare.</sgml>

Odniesienie do encji wewnętrznej „autor” nie jest zastępowane w tekście zastępującym encję wewnętrzną „podpis”. Zamiast tego jest on zastępowany tylko wtedy, gdy odwołanie do encji „sygnatura” jest analizowane w treści elementu „sgml”, ale tylko przez weryfikację parserów (parsery niewalidujące nie zastępują odwołań do encji występujących w treści elementu lub w wartościach atrybutów, w treści dokumentu.

Jest to możliwe, ponieważ tekst zastępujący określony w definicjach encji wewnętrznych pozwala na rozróżnienie między odwołaniami do encji parametrycznych (które są wprowadzane przez znak „%” i których zastąpienie dotyczy przeanalizowanej zawartości DTD) a odwołaniami do encji ogólnych (wprowadzanymi przez znak „&”, którego zastąpienie jest opóźnione, dopóki nie zostaną skutecznie przeanalizowane i zweryfikowane). Znak "%" służący do wprowadzania odwołań do jednostki parametrycznej w DTD traci swoją specjalną rolę poza DTD i staje się znakiem dosłownym.

Jednak odniesienia do predefiniowanych jednostek znakowych są zastępowane wszędzie tam, gdzie występują, bez konieczności sprawdzania parsera (są one wprowadzane tylko przez znak „&”).

Deklaracje notacji

Notacje są używane w SGML lub XML. Zapewniają pełne odniesienie do nieprzeanalizowanych zewnętrznych encji, których interpretację pozostawia się aplikacji (która interpretuje je bezpośrednio lub samodzielnie pobiera zewnętrzną encję), przypisując im prostą nazwę, która jest użyteczna w treści dokumentu. Na przykład notacje mogą być używane do odwoływania się do danych innych niż XML w dokumencie XML 1.1. Na przykład, aby dodać adnotacje do obrazów SVG, aby powiązać je z określonym rendererem:

<!NOTATION type-image-svg SYSTEM "image/svg">

To deklaruje typ MIME obrazów zewnętrznych z tym typem i kojarzy go z nazwą notacji „type-image-svg”. Jednak nazwy notacji zazwyczaj są zgodne z konwencją nazewnictwa, która jest specyficzna dla aplikacji generującej lub używającej notacji: notacje są interpretowane jako dodatkowe metadane, których efektywną treścią jest jednostka zewnętrzna i albo PUBLIC FPI, zarejestrowany w katalogach wykorzystywanych przez XML, albo Parsery SGML lub SYSTEM URI, których interpretacja jest zależna od aplikacji (tutaj typ MIME, interpretowany jako względny URI, ale może to być bezwzględny URI do konkretnego renderera, lub URN wskazujący specyficzny dla systemu operacyjnego identyfikator obiektu, taki jak UUID).

Zadeklarowana nazwa notacji musi być unikalna w ramach całej deklaracji typu dokumentu, tj. w podzbiorze zewnętrznym jak i podzbiorze wewnętrznym, przynajmniej dla zgodności z XML.

Notacje mogą być powiązane z nieprzeanalizowanymi jednostkami zewnętrznymi zawartymi w treści dokumentu SGML lub XML. PUBLICLub SYSTEMparametr tych podmiotów zewnętrznych określa FPI i / lub URI gdzie nieanalizowanego dane podmiotu zewnętrznego znajduje, a dodatkowy NDATAparametr tych zdefiniowanych podmiotów określa dodatkowego zapisu (tj skutecznie typ tutaj MIME). Na przykład:

<!DOCTYPE sgml [
  <!ELEMENT sgml (img)*>

  <!ELEMENT img EMPTY>
  <!ATTLIST img
     data ENTITY #IMPLIED>

  <!ENTITY   example1SVG     SYSTEM "example1.svg" NDATA example1SVG-rdf>
  <!NOTATION example1SVG-rdf SYSTEM "example1.svg.rdf">
]>
<sgml>
  <img data="example1SVG" />
</sgml>

W treści dokumentu SGML te zewnętrzne jednostki (którego nazwa jest określona między "&" i ";") nie są zastępowane jak zwykłe nazwane jednostki (zdefiniowane wartością CDATA), ale pozostają jako odrębne nieprzeanalizowane tokeny, które mogą być używane jako wartość atrybutu elementu (jak wyżej) lub w treści elementu, pod warunkiem, że albo DTD zezwala na takie zewnętrzne podmioty w zadeklarowanym typie zawartości elementów lub w zadeklarowanym typie atrybutów (tutaj ENTITYtyp dataatrybutu ) lub parser SGML nie sprawdza poprawności zawartości.

Notacje można również skojarzyć bezpośrednio z elementami jako dodatkowe metadane, bez kojarzenia ich z inną encją zewnętrzną, podając ich nazwy jako możliwe wartości niektórych dodatkowych atrybutów (również zadeklarowanych w DTD w ramach deklaracji elementu). Na przykład: <!ATTLIST ...>

<!DOCTYPE sgml [
  <!ELEMENT sgml (img)*>
   <!--
     the optional "type" attribute value can only be set to this notation.
   -->
  <!ATTLIST sgml
    type  NOTATION (
      type-vendor-specific ) #IMPLIED>

  <!ELEMENT img ANY> <!-- optional content can be only parsable SGML or XML data -->
   <!--
     The optional "title" attribute value must be parsable as text.
     The optional "data" attribute value is set to an unparsed external entity.
     The optional "type" attribute value can only be one of the two notations.
   -->
  <!ATTLIST img
    title CDATA              #IMPLIED
    data  ENTITY             #IMPLIED
    type  NOTATION (
      type-image-svg |
      type-image-gif )       #IMPLIED>

  <!--
    Notations are referencing external entities and may be set in the "type" attributes above,
    or must be referenced by any defined external entities that cannot be parsed.
  -->
  <!NOTATION type-image-svg       PUBLIC "-//W3C//DTD SVG 1.1//EN"
     "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
  <!NOTATION type-image-gif       PUBLIC "image/gif">
  <!NOTATION type-vendor-specific PUBLIC "application/VND.specific+sgml">

  <!ENTITY example1SVGTitle "Title of example1.svg"> <!-- parsed internal entity -->
  <!ENTITY example1SVG      SYSTEM "example1.svg"> <!-- parsed external entity -->
  <!ENTITY example1GIFTitle "Title of example1.gif"> <!-- parsed internal entity -->
  <!ENTITY example1GIF      SYSTEM "example1.gif" NDATA type-image-gif> <!-- unparsed external entity -->
]>
<sgml type="type-vendor-specific">
  <!-- an SVG image is parsable as valid SGML or XML text -->
  <img title="&example1SVGTitle;" type="type-image-svg">&example1SVG;</img>

  <!-- it can also be referenced as an unparsed external entity -->
  <img title="&example1SVGTitle;" data="example1SVG" />

  <!-- a GIF image is not parsable and can only be referenced as an external entity -->
  <img title="&example1GIFTitle;" data="example1GIF" />
</sgml>

Powyższy przykład pokazuje notację o nazwie „type-image-svg”, która odwołuje się do standardowego publicznego FPI i identyfikatora systemowego (standardowego URI) dokumentu SVG 1.1, zamiast określania samego identyfikatora systemowego, jak w pierwszym przykładzie (który był względny identyfikator URI interpretowany lokalnie jako typ MIME). Ta adnotacja jest przywoływana bezpośrednio w nieprzeanalizowanym atrybucie „type” elementu „img”, ale jego zawartość nie jest pobierana. Deklaruje również inną notację dla aplikacji specyficznej dla dostawcy, aby dodać adnotację do elementu głównego „sgml” w dokumencie. W obu przypadkach zadeklarowana notacja nazwana jest używana bezpośrednio w zadeklarowanym atrybucie „type”, którego zawartość jest określona w DTD za pomocą atrybutu typu „NOTATION” (ten atrybut „type” jest również zadeklarowany dla elementu „sgml” jak dla elementu „img”).

Jednak atrybut „title” elementu „img” określa encję wewnętrzną „example1SVGTitle”, której deklaracja nie definiuje adnotacji, więc jest analizowana przez sprawdzanie parserów, a tekst zastępujący encję to „Title of example1.svg”.

Zawartość elementu „img” odwołuje się do innej zewnętrznej encji „example1SVG”, której deklaracja również nie definiuje notacji, więc jest również analizowana przez sprawdzanie parserów, a tekst zastępujący encję znajduje się w jego zdefiniowanym identyfikatorze SYSTEMU „example1.svg” ( interpretowany również jako względny identyfikator URI). Efektywną treścią elementu „img” jest zawartość tego drugiego zasobu zewnętrznego. Różnica w stosunku do obrazu GIF polega na tym, że obraz SVG jest analizowany w dokumencie SGML, zgodnie z deklaracjami w DTD, gdzie obraz GIF jest po prostu przywoływany jako nieprzezroczysty obiekt zewnętrzny (który nie jest analizowany z SGML) poprzez jego " data” (którego typem wartości jest nieprzezroczysta ENTITY).

W wartości atrybutów ENTITY można podać tylko jedną nazwę notacji (w SGML, XML 1.0 lub XML 1.1 nie ma obsługi wielu nazw notacji w tym samym zadeklarowanym zewnętrznym ENTITY, więc potrzebne są oddzielne atrybuty). Można jednak odwoływać się do wielu jednostek zewnętrznych (na liście nazw rozdzielonych spacjami) w atrybutach zadeklarowanych z typem ENTITIES, a każda nazwana jednostka zewnętrzna jest również zadeklarowana z własną notacją).

Notacje są również całkowicie nieprzejrzyste dla parserów XML i SGML, więc nie różnią się od typu jednostki zewnętrznej, do której mogą się odwoływać (dla tych parserów mają po prostu unikalną nazwę powiązaną z publicznym identyfikatorem (FPI) i/lub identyfikator systemu (URI)).

Niektóre aplikacje (ale nie same parsery XML lub SGML) pozwalają również na pośrednie odwoływanie się do notacji poprzez nazywanie ich w "URN:''name''"wartości standardowego atrybutu CDATA, wszędzie tam, gdzie można podać URI. Jednak to zachowanie jest specyficzne dla aplikacji i wymaga, aby aplikacja utrzymywała katalog znanych adresów URN w celu przekształcenia ich w notacje, które zostały przeanalizowane w standardowym analizatorze składniowym SGML lub XML. To zastosowanie pozwala na definiowanie notacji tylko w DTD przechowywanym jako jednostka zewnętrzna i odwoływanie się tylko do zewnętrznego podzbioru dokumentów, a także pozwala na zachowanie zgodności tych dokumentów z walidacją parserów XML lub SGML, które nie mają bezpośredniego wsparcia dla notacji.

Notacje nie są używane w HTML ani w podstawowych profilach XHTML i SVG, ponieważ:

  • Do wszystkich encji zewnętrznych używanych przez te standardowe typy dokumentów odwołują się proste atrybuty, zadeklarowane za pomocą typu CDATA w ich standardowym DTD (takie jak atrybut „href” elementu kotwicy „a” lub atrybut „src” obrazu „ img", którego wartości są interpretowane jako URI, bez konieczności katalogowania publicznych identyfikatorów, czyli znanego FPI)
  • Do wszystkich zewnętrznych jednostek dla dodatkowych metadanych odwołuje się:
    • Dodatkowe atrybuty (takie jak type , który wskazuje typ MIME encji zewnętrznej lub atrybut charset , który wskazuje jej kodowanie)
    • Dodatkowe elementy (takie jak link lub meta w HTML i XHTML) w ramach własnych atrybutów
    • Standardowe pseudoatrybuty w XML i XHTML (takie jak xml:lang lub xmlns i xmlns:* dla deklaracji przestrzeni nazw).

Nawet podczas walidacji parserów SGML lub XML 1.0 lub XML 1.1 zewnętrzne encje, do których odwołuje się FPI i/lub URI w zadeklarowanych notacjach, nie są automatycznie pobierane przez same parsery. Zamiast tego parsery te po prostu dostarczają do aplikacji przeanalizowane FPI i/lub URI związane z notacjami znalezionymi w przeanalizowanym dokumencie SGML lub XML oraz z funkcją słownika zawierającego wszystkie nazwy notacji zadeklarowane w DTD; te parsery walidujące sprawdzają również unikalność deklaracji nazw notacji i zgłaszają błąd walidacji, jeśli jakieś nazwy notacji są używane gdziekolwiek w DTD lub w treści dokumentu, ale nie są zadeklarowane:

  • Jeśli aplikacja nie może użyć żadnej notacji (lub jeśli ich FPI i/lub URI są nieznane lub nieobsługiwane w katalogu lokalnym), te notacje mogą być ignorowane przez aplikację po cichu lub aplikacja może sygnalizować błąd.
  • W przeciwnym razie aplikacje same decydują, jak je zinterpretować, a następnie, czy zewnętrzne encje muszą zostać pobrane, a następnie osobno przeanalizowane.
  • Aplikacje mogą następnie sygnalizować błąd, jeśli taka interpretacja, pobieranie lub oddzielne analizowanie nie powiedzie się.
  • Nierozpoznane notacje, które mogą spowodować, że aplikacja zasygnalizuje błąd, nie powinny blokować interpretacji walidowanego dokumentu przy ich użyciu.

DTD XML i walidacja schematu

Składnia XML DTD jest jednym z kilku języków schematów XML . Jednak wiele języków schematów nie zastępuje w pełni DTD XML. Warto zauważyć, że XML DTD umożliwia definiowanie encji i notacji, które nie mają bezpośrednich odpowiedników w XML-u bez DTD (ponieważ encje wewnętrzne i parsowalne encje zewnętrzne nie są częścią języków schematów XML, a inne nieprzeanalizowane encje zewnętrzne i notacje nie mają prostych odwzorowań równoważnych w większość języków schematów XML).

Większość języków schematów XML zastępuje jedynie deklaracje elementów i deklaracje list atrybutów w taki sposób, że staje się możliwe parsowanie dokumentów XML za pomocą niewalidujących parserów XML (jeśli jedynym celem zewnętrznego podzbioru DTD było zdefiniowanie schematu). Ponadto dokumenty dla tych języków schematów XML muszą być analizowane oddzielnie, więc walidacja schematu dokumentów XML w trybie autonomicznym nie jest w rzeczywistości możliwa w tych językach: deklaracja typu dokumentu pozostaje niezbędna przynajmniej do identyfikacji (za pomocą Katalogu XML ) schemat używany w analizowanym dokumencie XML, który jest sprawdzany w innym języku.

Powszechnym błędem utrzymuje, że zakaz walidacji XML parser nie trzeba czytać deklaracji typu dokumentu, podczas gdy w rzeczywistości, deklaracji typu dokumentu musi nadal być zeskanowane do poprawnej składni, a także ważności deklaracji, a parser musi jeszcze przeanalizować wszystkie jednostki deklaracje w wewnętrznym podzbiorze i zastąp teksty zastępcze encji wewnętrznych występujące w dowolnym miejscu w deklaracji typu dokumentu lub w treści dokumentu.

Niewalidujący parser może jednak zdecydować, by nie czytać parsable podmiotów zewnętrznych (w tym podzbiorze zewnętrznego ), i nie ma na cześć zawartości ograniczeń modelu zdefiniowane w deklaracji elementów i w deklaracjach lista atrybutów.

Jeśli dokument XML zależy od parsowalnych zewnętrznych encji (w tym określonego zewnętrznego podzbioru lub parsowalnych zewnętrznych encji zadeklarowanych w wewnętrznym podzbiorze ), powinien on potwierdzić standalone="no"w swojej deklaracji XML . Walidację DTD można zidentyfikować za pomocą katalogów XML w celu pobrania określonego zewnętrznego podzbioru .

W poniższym przykładzie dokument XML jest zadeklarowany za pomocą, standalone="no"ponieważ ma zewnętrzny podzbiór w deklaracji typu dokumentu:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE people_list SYSTEM "example.dtd">
<people_list />

Jeśli deklaracja typu dokumentu XML zawiera dowolny identyfikator SYSTEM dla zewnętrznego podzbioru, nie może być bezpiecznie przetwarzana jako samodzielna: należy pobrać identyfikator URI, w przeciwnym razie mogą istnieć nieznane nazwane jednostki znakowe, których definicja może być potrzebna do poprawnego przeanalizowania efektywnego kodu XML składnia w wewnętrznym podzbiorze lub w treści dokumentu (parsowanie składni XML jest zwykle wykonywane po podstawieniu wszystkich nazwanych encji, z wyjątkiem pięciu encji, które są predefiniowane w XML i które są niejawnie zastępowane po przeanalizowaniu dokumentu XML na leksykalne leksyki). Jeśli zawiera tylko dowolny identyfikator PUBLIC, może być przetwarzany jako samodzielny, jeśli procesor XML zna ten identyfikator PUBLIC w swoim katalogu lokalnym, skąd może pobrać skojarzoną jednostkę DTD.

Przykład schematu XML DTD

Przykład bardzo prostego zewnętrznego XML DTD opisującego schemat listy osób może składać się z:

<!ELEMENT people_list (person)*>
<!ELEMENT person (name, birthdate?, gender?, socialsecuritynumber?)>
<!ELEMENT name (#PCDATA)>
<!ELEMENT birthdate (#PCDATA)>
<!ELEMENT gender (#PCDATA)>
<!ELEMENT socialsecuritynumber (#PCDATA)>

Biorąc ten wiersz po wierszu:

  1. people_listjest poprawną nazwą elementu, a instancja takiego elementu zawiera dowolną liczbę personelementów. W *oznacza nie może wynosić 0 lub więcej personelementów w obrębie people_listelementu.
  2. personjest poprawną nazwą elementu, a instancja takiego elementu zawiera jeden element o nazwie name, po którym następuje jeden o nazwie birthdate(opcjonalne), następnie gender(również opcjonalne) i socialsecuritynumber(także opcjonalne). ?Wskazuje, że element jest opcjonalny. Odwołanie do namenazwy elementu ma no ?, więc personelement musi zawierać nameelement.
  3. name jest poprawną nazwą elementu, a wystąpienie takiego elementu zawiera „przeanalizowane dane znakowe” (#PCDATA).
  4. birthdate jest poprawną nazwą elementu, a wystąpienie takiego elementu zawiera przeanalizowane dane znakowe.
  5. gender jest poprawną nazwą elementu, a wystąpienie takiego elementu zawiera przeanalizowane dane znakowe.
  6. socialsecuritynumber jest poprawną nazwą elementu, a wystąpienie takiego elementu zawiera przeanalizowane dane znakowe.

Poniżej znajduje się przykład pliku XML, który używa i jest zgodny z tym DTD. DTD jest tutaj przywoływane jako podzbiór zewnętrzny, poprzez specyfikator SYSTEM i URI. Zakłada, że ​​możemy zidentyfikować DTD za pomocą względnego identyfikatora URI „example.dtd”; "lista_ludzi" po "!DOCTYPE" mówi nam, że znaczniki główne lub pierwszy element zdefiniowany w DTD nazywa się "lista_ludzi":

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE people_list SYSTEM "example.dtd">
<people_list>
  <person>
    <name>Fred Bloggs</name>
    <birthdate>2008-11-27</birthdate>
    <gender>Male</gender>
  </person>
</people_list>

Można to wyrenderować w przeglądarce obsługującej XML (takiej jak Internet Explorer lub Mozilla Firefox ), wklejając i zapisując powyższy komponent DTD w pliku tekstowym o nazwie example.dtd, a plik XML w pliku tekstowym o innej nazwie, a następnie otwierając Plik XML z przeglądarką. Pliki powinny być zapisane w tym samym katalogu. Jednak wiele przeglądarek nie sprawdza, czy dokument XML jest zgodny z regułami w DTD; są one wymagane tylko do sprawdzenia, czy DTD jest poprawny składniowo. Ze względów bezpieczeństwa mogą również zdecydować się nie czytać zewnętrznego DTD.

To samo DTD można również osadzić bezpośrednio w samym dokumencie XML jako podzbiór wewnętrzny, umieszczając je w [nawiasach kwadratowych] w deklaracji typu dokumentu, w którym to przypadku dokument nie jest już zależny od encji zewnętrznych i może być przetwarzany w trybie autonomicznym :

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<!DOCTYPE people_list [
  <!ELEMENT people_list (person*)>
  <!ELEMENT person (name, birthdate?, gender?, socialsecuritynumber?)>
  <!ELEMENT name (#PCDATA)>
  <!ELEMENT birthdate (#PCDATA)>
  <!ELEMENT gender (#PCDATA)>
  <!ELEMENT socialsecuritynumber (#PCDATA)>
]>
<people_list>
  <person>
    <name>Fred Bloggs</name>
    <birthdate>2008-11-27</birthdate>
    <gender>Male</gender>
  </person>
</people_list>

Dostępne są alternatywy dla DTD (do określania schematów):

  • XML Schema , określany również jako XML Schema Definition (XSD), osiągnął status Rekomendacji w ramach W3C i jest popularny w przypadku „zorientowanego na dane” (tj. transakcyjnego niepublikowania) użycia XML ze względu na silniejsze typowanie i łatwiejsze podróżowanie do deklaracji Java. Większość świata wydawniczego odkryła, że ​​dodatkowa złożoność XSD nie przyniosłaby im żadnych szczególnych korzyści, więc DTD są tam nadal znacznie bardziej popularne. Definicja schematu XML sama w sobie jest dokumentem XML, podczas gdy DTD nie jest.
  • RELAX NG , który jest również częścią DSDL , jest międzynarodowym standardem ISO. Jest bardziej wyrazisty niż XSD, a jednocześnie zapewnia prostszą składnię, ale wsparcie dla oprogramowania komercyjnego nadchodzi powoli.

Bezpieczeństwo

DTD XML może służyć do tworzenia ataku typu „odmowa usługi” (DoS) poprzez definiowanie zagnieżdżonych jednostek, które rozwijają się wykładniczo, lub wysyłanie parsera XML do zasobu zewnętrznego, który nigdy nie powraca.

Z tego powodu .NET Framework zapewnia właściwość, która pozwala zabronić lub pominąć analizowanie DTD, a najnowsze wersje aplikacji Microsoft Office (Microsoft Office 2010 i nowsze) odmawiają otwierania plików XML zawierających deklaracje DTD.

Zobacz też

Bibliografia

Linki zewnętrzne