XHTML

W tym rozdziale dowiesz się...

Co to jest XHTML?

XHTML to skrót od Extensible Hypertext Markup Language, czyli Rozszerzalny Hipertekstowy Język Oznaczania. Reformuje on znane zasady języka HTML 4 w taki sposób, aby były zgodne z XML (Extensible Markup Language - Rozszerzalny Język Oznaczania). XML czerpie swoją moc i elastyczność z języka SGML (Standard Generalized Markup Language - Standardowy Uogólniony Język Oznaczania). Biorąc te zalety, XML pomija wiele bardziej skomplikowanych cech języka SGML, które przyczyniały się do utrudnienia i podrożenia procesu projektowania.

Jakie korzyści daje przejście z HTML na XHTML?

  • Dokumenty XHTML są zgodne ze składnią XML, więc mogą być łatwo przeglądane, edytowane i walidowane (sprawdzane) przez standardowe narzędzia XML.
  • Dokumenty XHTML mogą być napisane tak, aby działały równie dobrze lub nawet lepiej zarówno w przeglądarkach obsługujących HTML 4 jak i XHTML.
  • Dokumenty XHTML mogą zawierać skrypty i applety, które bazują na języku DOM (Document Object Model) zgodnym z HTML jak i XHTML.
  • Podczas gdy rodzina języków XHTML będzie ewoluować, dokumenty zgodne z XHTML będą bardziej przyjazne do działania wewnątrz i pomiędzy różnymi środowiskami XHTML.
  • W języku XML stosunkowo łatwo można wprowadzać nowe elementy i atrybuty. Rodzina języków XHTML została zaprojektowana tak, aby przystosować te rozszerzenia do modułów XHTML. Moduły pozwalają tworzyć kombinacje istniejących i nowych cech podczas budowania serwisów oraz projektowania nowych przeglądarek.
  • Serwery, proxy i przeglądarki będą zdolne do przeprowadzania lepszej transformacji treści. Dokumenty zgodne z XHTML będą poprawnie interpretowane w każdej przeglądarce zgodnej z tym językiem.

Czy HTML umarł?

Pierwsza oficjalna odsłona języka HTML 4.0 odbyła się 18 grudnia 1997, a ostatnia poprawka do wersji 4.01 została wprowadzona 24 grudnia 1999. Można pomyśleć, że język HTML to już przeszłość. Na szczęście niezupełnie jest to prawdą. Język XHTML, który jest aktualnym standardem w tworzeniu serwisów WWW, opiera się na specyfikacji HTML 4.01, tzn. definiuje dokładnie te same znaczniki, atrybuty i sposoby budowania dokumentów. Jednak wprowadza przy tym pewne obostrzenia, które pozwalają dostosować składnię do języka XML, który od jakiegoś czasu wyznacza trendy rozwoju aplikacji przenośnych. Zatem zdobyta wcześniej wiedza o języku HTML nie pójdzie na marne i nie musisz się uczyć wszystkiego od nowa. Aby pisać dokumenty zgodne z aktualnymi standardami i trendami wystarczy, że przyswoisz sobie kilka prostych dodatkowych zasad opisanych poniżej.

Wymagania stawiane dokumentom XHTML

  1. Dokumenty XHTML muszą spełniać ograniczenia podane w DTD (Document Type Definition - Definicja Typu Dokumentu).
  2. Elementem podstawowym (root) w dokumencie musi być html.
  3. Element podstawowy (html) musi zawierać deklarację xmlns identyfikującą przestrzeń nazw XHTML, która stanowi zbiór nazw używanych w dokumencie jako typy elementów i nazwy atrybutów:
    <html xmlns="http://www.w3.org/1999/xhtml" lang="pl">
  4. W dokumencie obowiązkowo musi być wstawiona deklaracja typu dokumentu przed elementem podstawowym (czyli przed html). W języku XHTML 1.0 są trzy możliwe do zastosowania wersje DTD:
    • Strict (ścisła)
      <!DOCTYPE html 
      	PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
      	"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    • Transitional (przejściowa)
      <!DOCTYPE html 
      	PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
      	"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    • Frameset (ramkowa)
      <!DOCTYPE html 
      	PUBLIC "-//W3C//DTD XHTML 1.0 Frameset//EN"
      	"http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd">
    Natomiast XHTML 1.1 dopuszcza tylko jedną wersję DTD:
    <!DOCTYPE
    	html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
    	"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">

Deklaracja XML w postaci (zarówno dla XHTML 1.0 jak i XHTML 1.1):

<?xml version="1.0" encoding="UTF-8"?>

nie jest wymagana, ale mocno zaleca się jej stosowanie. Taka deklaracja jest wymagana, jeśli kodowanie znaków w dokumencie jest inne niż UTF-8 i UTF-16, a jednocześnie kodowanie nie jest określone przez żaden protokół wyższego rzędu, jak np. nagłówek HTTP "Content-Type" wysyłany przez serwer.

Oto przykład typowego dokumentu XHTML (1.0) z dołączoną deklaracją XML:

<?xml version="1.0" encoding="ISO-8859-2"?>
<!DOCTYPE html 
	PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
	"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="pl">
	<head>
		<title>Tytuł dokumentu</title>
	</head>
	<body>
		<p>Przejdź do <a href="http://example.org/">example.org</a>.</p>
	</body>
</html>

Na serwerach obsługujących skrypty PHP (pliki z rozszerzeniami *.php) po wpisaniu deklaracji XML może wystąpić błąd. Aby go uniknąć, należy zamiast deklaracji XML wpisać:

<?php echo '<'.'?xml version="1.0" encoding="UTF-8"?'.'>'."\n"; ?>

Niektóre przeglądarki mogą nie interpretować deklaracji XML i z tego powodu wyświetlać dokument w sposób nieoczekiwany. Wpisanie deklaracji XML w przeglądarce MSIE 7.0 i starszych powoduje przełączenie w tryb Quirks.

Podanie tej deklaracji nie jest obowiązkowe, jednak wtedy dokument może mieć tylko domyślne kodowanie znaków: UTF-8 lub UTF-16, chyba że serwer prześle odpowiedni nagłówek HTTP "Content-Type". W celu zapewnienia kompatybilności wstecz powinno się dodać w nagłówku dokumentu również tradycyjną deklarację strony kodowej, np.:

<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-2">

Różnice między HTML 4 a XHTML 1.0

  1. Znaczniki należy zamykać obowiązkowo w kolejności odwrotnej do ich otwierania:
    Poprawnie: <p>wewnątrz paragrafu jest <em>emfaza</em>.</p>
    Niepoprawnie: <p>wewnątrz paragrafu jest <em>emfaza.</p></em>
  2. Nazwy znaczników i atrybutów obowiązkowo muszą być pisane małymi literami.
  3. Dla elementów niepustych znaczniki zamykające są obowiązkowe:
    Poprawnie: <p>tutaj jest paragraf.</p><p>tutaj jest następny paragraf.</p>
    Niepoprawnie: <p>tutaj jest paragraf.<p>tutaj jest następny paragraf.
  4. Wartości atrybutów muszą być zawsze ujęte w cudzysłowy:
    Poprawnie: <td rowspan="3">
    Niepoprawnie: <td rowspan=3>
  5. Nie można minimalizować atrybutów logicznych:
    Poprawnie: <dl compact>
    Niepoprawnie: <dl compact>
  6. Puste elementy muszą mieć znacznik zamykający albo ich znacznik otwierający musi się kończyć na >:
    Poprawnie: <br><br><hr></hr>
    Niepoprawnie: <br><hr>

    Ze względu na kompatybilność wstecz lepiej jest używać formy ze spacją przed końcowym ukośnikiem: <br>. W celu zapewnienia kompatybilności zaleca się też nie używać formy zminimalizowanej, a tradycyjnej metody dla znaczników, których zamykanie w HTML 4 było opcjonalne, tzn. np. tak: <p> </p>, a nie tak: <p>.

  7. Wartości atrybutów są przetwarzane następująco:
    • Białe znaki na początku i na końcu są usuwane.
    • Kilka sąsiadujących białych znaków (w tym także znaki nowej linii) jest zamieniane na jeden.
  8. Skrypty osadzone i wewnętrzne arkusze stylów (element style) należy wstawiać w następujący sposób:
    <script>
    <![CDATA[
    ...zawartość skryptu (może zawierać bezpośrednio znaki: <, >, &)...
    ]]>
    </script>

    Jest to konieczne, jeśli wewnętrzny skrypt lub arkusz stylów zawiera znaki: <, >, &, ponieważ w takim przypadku procesor XML potraktuje je jako znaczniki lub początek encji (znaków specjalnych).

    Uwaga! Przeglądarki mogą nie obsługiwać tej metody. Dla zapewnienia zgodności z językiem XHTML skrypty i arkusze stylów, które zawierają znaki: <, &, ]]> lub -- można umieścić w zewnętrznym pliku.

    Jeżeli nie jest możliwe umieszczenie skryptu bądź arkusza CSS w zewnętrznym pliku, co jest zalecane, można wykorzystać następującą metodę:

    <style>
    /* <![CDATA[ */
    ...zawartość arkusza CSS (może zawierać bezpośrednio znaki: <, >, &)...
    /* ]]> */
    </style>
    
    <script>
    // <![CDATA[
    ...zawartość skryptu (może zawierać bezpośrednio znaki: <, >, &)...
    // </script>
    
    albo
    
    <script>
    /* <![CDATA[ */
    ...zawartość skryptu (może zawierać bezpośrednio znaki: <, >, &)...
    /* ]]> */
    </script>

    Nie należy ukrywać osadzonych skryptów ani wewnętrznych arkuszy stylów przed starszymi przeglądarkami w komentarzach HTML <!-- ... -->. W języku XML istnieje zasada, że przed etapem właściwego parsowania dokumentu, można z niego usunąć wszystkie komentarze. Oznaczałoby to, że tego typu skrypty i arkusze w ogóle nie byłyby brane pod uwagę przy renderowaniu strony!

    Oczywiście w takim przypadku w przestarzałych przeglądarkach cała zawartość takiego arkusza bądź skryptu wyświetli się na ekranie, ponieważ nie jest ukryta w komentarzach HTML. Nie ma się co jednak zbytnio tym przejmować, ponieważ obecnie właściwie wszystkie popularne przeglądarki od dawna obsługują zarówno skrypty jak i style CSS. Po raz kolejny trzeba jednak zwrócić uwagę, że zapisanie skryptu czy arkusza w zewnętrznym pliku całkowicie eliminuje ten problem. Starsze przeglądarki po prostu nie pobiorą takiego pliku, a na ekranie nie wyświetli się żadna niepotrzebna treść.

  9. Nie wolno zagnieżdżać (umieszczać jeden w drugim) następujących znaczników (dotyczy wszystkich poziomów zagnieżdżania, tzn. wszystkich potomków elementu):
    a
    nie może zawierać innych elementów a.
    pre
    nie może zawierać elementów: img, object, big, small, sub, sup.
    button
    nie może zawierać elementów: input, select, textarea, label, button, form, fieldset, iframe, isindex.
    label
    nie może zawierać innych elementów label.
    form
    nie może zawierać innych elementów form.
  10. Atrybut name dla znaczników a, applet, form, frame, iframe, img, map jest zdeprecjonowany. Należy stosować zamiast niego atrybut id.
    W celu zapewnienia kompatybilności wstecz można używać jednocześnie obu atrybutów, np.:
    <a id="identyfikator" name="identyfikator">...</a>
    W przypadku konfliktów ważniejsza będzie wartość id.
  11. Wartości atrybutów domyślnych są zawsze definiowane małymi literami. Na przykład jeśli nie podamy jawnie atrybutu type dla znacznika input, zostanie dla niego przyjęta wartość type="text", a nie type="TEXT".
  12. Znaki specjalne (tzw. encje) w języku HTML można zapisywać używając wartości szesnastkowych (HEX), np.: &#Xnn; lub &#xnn;, gdzie "nn" to liczba szesnastkowa. XHTML pozwala tylko na drugą wersję, tzn. &#xnn;.

Zarówno w języku HTML jak i XHTML w kodzie strony nie powinien pojawić się bezpośrednio znak & - zamiast niego trzeba zawsze wpisywać &amp;. Reguła ta dotyczy nie tylko zwykłej treści dokumentu, ale również wartości atrybutów:

Poprawnie: <a href="http://example.org/index.php?var1=1&amp;var2=2">...</a>
Niepoprawnie: <a href="http://example.org/index.php?var1=1&var2=2">...</a>

Aby zapewnić zgodność z językiem XML, przy wstawianiu wewnętrznego arkusza stylów trzeba się posłużyć następującą metodą (pierwsza linia kodu dołącza zewnętrzny arkusz stylów):

<?xml-stylesheet href="zewnetrzny.css"?>
<?xml-stylesheet href="#internalStyle"?>
<!DOCTYPE html 
	PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
	"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="pl">
<head>
<title>Przykład wewnętrznego arkusza CSS</title>
<style id="internalStyle">
	code {
		color: green;
		font-family: monospace;
		font-weight: bold;
	}
</style>
</head>
<body>
<p>
	To jest tekst, który używa naszego
	<code>wewnętrznego arkusza stylów</code>.
</p>
</body>
</html>

W MSIE 6.0 i starszych, w przypadku wpisania deklaracji XML, zawartość od początku dokumentu do otwarcia znacznika <html... nie może przekroczyć 250 bajtów (wliczając białe znaki - w tym znaki nowej linii). W przeciwnym razie dokument zostanie wyświetlony jako XML, bez względu nawet na wysłany nagłówek HTTP. W MSIE 7.0 wszystko jest już w porządku.

Wyświetlenie dokumentu XHTML jako czystego XML wywoła tak duże błędy w prezentacji strony, że właściwie będzie ona zupełnie nieczytelna: większość elementów błędnie wystylizowanych, a cały tekst umieszczony w jednym długim akapicie! W niektórych przypadkach dokument może w ogóle utracić formatowanie i zostanie wyświetlony jak drzewo elementów XML. Pamiętaj, że w systemie Windows znak nowej linii ma długość dwóch bajtów. Ponadto w przypadku kodowania UTF-8 niektóre znaki, jak np. polskie litery, składają się z dwóch bajtów, a w UTF-16 wszystkie znaki mają długość dwóch bajtów.

Znak &apos; przedstawiający apostrof (') pojawił się dopiero w XML 1.0, a nie występuje w HTML. W celu zapewnienia kompatybilności wstecz, zamiast bezpośredniej nazwy znaku można stosować &#39;.

Źródło: XHTML 1.0 The Extensible HyperText Markup Language

Różnice między XHTML 1.0 Strict a XHTML 1.1

W XHTML 1.1 ostatecznie usunięto elementy i atrybuty zdeprecjonowane. Założeniem było stworzenie języka bogatego w funkcjonalność strukturalną, ale polegającego na arkuszach stylów przy prezentacji.

  1. Atrybut lang został usunięty. Zamiast niego należy stosować tylko xml:lang.
  2. Dla elementów a oraz map atrybut name został usunięty. Zamiast niego należy stosować tylko id.
  3. Wprowadzono obsługę tzw. ruby, czyli specjalnych krótkich wstawek obok bazowego tekstu, używanych zwykle w dokumentach wschodnioazjatyckich do wskazania wymowy lub wstawienia krótkiej adnotacji (znaczniki: ruby, rbc, rtc, rb, rt, rp).

Źródło: XHTML 1.1 - Module-based XHTML

Typy MIME dokumentów XHTML

(interpretuje: Internet Explorer 9.0, Firefox, Opera, Chrome)

MIME to skrót od Multipurpose Internet Mail Extensions, czyli Uniwersalne Internetowe Rozszerzenia Poczty. Jest to internetowy standard zaprojektowany pierwotnie do obsługi przesyłania plików w listach poczty elektronicznej. Rozwinął się on jednak na tyle, że aktualnie jest niekwestionowanym standardem we wszystkich usługach internetowych, gdzie podstawowym zadaniem było przesyłanie tekstu, a pojawiło się zapotrzebowanie przesyłania danych innego typu. Nie trudno się domyślić, że MIME określa również typ dokumentów HTML oraz XHTML, ponieważ jak sama nazwa wskazuje nie są one zwykłym tekstem ale hipertekstem. Przed każdym plikiem czy dokumentem przesyłanym przez sieć WWW, dołączane są specjalne dane, zwane nagłówkiem HTTP, w którym znajduje się m.in. typ MIME. To właśnie dzięki niemu, przeglądarka użytkownika "wie", co ma dalej zrobić z plikiem: jeżeli jest to dokument (X)HTML, powinna go wyświetlić, a natomiast pliki multimedialne mogą być otwierane w zewnętrznych odtwarzaczach lub zapisywane na dysku.

Jeżeli chodzi o dokumenty HTML, typ MIME możemy zaobserwować na początku ich treści (w sekcji HEAD) - jest to deklaracja strony kodowej:

<meta http-equiv="Content-Type" content="text/html; charset=utf-8">

Oto spis typów MIME, z którymi mogą być przesyłane dokumenty HTML i XHTML:

MIMEHTML 4XHTML 1.0
(kompatybilność wstecz)
XHTML 1.0XHTML 1.1
text/htmlpowinienmożenie powiniennie powinien
application/
xhtml+xml
nie możepowinienpowinienpowinien
application/
xml
nie możemożemożemoże
text/xmlnie możemożemożemoże

Źródło: XHTML Media Types

text/html
Typ odpowiedni dla dokumentów HTML oraz XHTML 1.0, których autorzy pragną, aby mogły być wyświetlane w przeglądarkach, które nie obsługują języka XHTML w pełni. Dokumenty tego typu nie będą przetwarzane zgodnie z wymogami języka XML. Będzie to miało wpływ również na zachowanie skryptów JavaScript, korzystających ze standardu DOM oraz reguły arkuszy CSS. Domyślnym kodowaniem znaków - tzn. jeśli nie określimy inaczej - zwykle jest UTF-8, jednak może to zależeć od ustawień przeglądarki.
application/xhtml+xml
Typ specjalnie zaprojektowany dla dokumentów XHTML i najbardziej dla nich odpowiedni. Dokumenty tego typu są przetwarzane zgodnie z wymogami języka XML. Strona kodowania znaków podlega tym samym ograniczeniom i regułom, co dla typu application/xml.
application/xml
Ogólny typ języka XML. Dokumenty XHTML mogą być również serwowane z tym typem, jednak w takim przypadku niektóre przeglądarki mogą ich nie wyświetlić zgodnie z regułami języka XHTML, tzn. np. linki mogą nie być "klikalne"! Domyślny system kodowania znaków to UFT-8 lub UTF-16. Inne kodowanie można określić za pomocą nagłówka HTTP lub deklaracji XML. Deklaracja strony kodowej za pomocą znacznika META nie jest rozpoznawana (w tego typu dokumentach XHTML nie powinno się jej wstawiać)!
text/xml
Inny ogólny typ przeznaczony dla języka XML. Jest on preferowany dla dokumentów XML, które w formie nieprzetworzonej, tzn. czystego kodu źródłowego, mogą być bez większych trudności odczytane przez zwykłego użytkownika. W przeciwnym wypadku zaleca się stosowanie application/xml. Serwowanie dokumentów XHTML z tym typem również jest możliwe, jednak mogą wystąpić dokładnie te same problemy, co w przypadku application/xml. Dlatego zaleca się stosowanie application/xhtml+xml!

Jak można łatwo zauważyć, najodpowiedniejszym typem MIME dla dokumentów HTML jest text/html. Dokumenty XHTML 1.0 mogą być przesyłane z tym samym typem zwłaszcza, jeśli są napisane w sposób, umożliwiający ich wyświetlenie przez przeglądarki, które obsługują tylko podstawowy język HTML. Natomiast dokumenty XHTML 1.1 powinny być przesyłane z typem application/xhtml+xml - w tym przypadku text/html nie jest zalecane.

Ponadto trzeba zdawać sobie sprawę, że sama deklaracja strony kodowej nie wystarczy do określenia typu MIME! Konieczne jest przesłanie odpowiedniego nagłówka HTTP, poprzedzającego właściwą treść dokumentu. W języku HTML (ani XHTML) nie ma takiej możliwości. W przypadku dokumentów HTML lub XHTML 1.0 kompatybilnych wstecz, nie trzeba się jednak tym martwić. Wystarczy nadać plikowi odpowiednie rozszerzenie - zwykle *.html. Z dokumentami XHTML 1.1 może być jednak większy kłopot. Teoretycznie ten sam mechanizm moglibyśmy uzyskać, nadając plikom rozszerzenie *.xhtml. Niestety nie wszystkie przeglądarki obsługują pliki z typem MIME application/xhtml+xml. Przykładowo: Internet Explorer 8.0 i starsze zamiast wyświetlić stronę, próbuje pobrać plik na dysk, co oczywiście uniemożliwia wyświetlenie zawartości strony! Wyniki testu rozpoznawania typów MIME przez różne przeglądarki można obejrzeć na stronie organizacji W3C: XHTML media type test.

UWAGA!
Typ MIME application/xhtml+xml jest wspierany przez przeglądarkę Internet Explorer dopiero od wersji 9.0, natomiast typy text/xml i application/xml są interpretowane z błędami!

Z problemem można sobie poradzić poprzez tzw. negocjację zawartości, która polega na wysłaniu takiego typu MIME, który jest obsługiwany przez przeglądarkę. Niestety statyczny język XHTML na to nie pozwala. Można to natomiast osiągnąć np. przy pomocy PHP:

Aby poniższy skrypt działał poprawnie, konieczna jest obsługa języka PHP na serwerze!

  1. Utwórz katalog o nazwie mime, a w nim plik pod nazwą mime.inc.php i zapisz w nim następujący kod (na początku można podać własne ustawienia):
    <?php
    /**
     * XHTML MIME Negotiation
     * @version 2.2.2
     * @author Sławomir Kokłowski {@link http://www.kurshtml.edu.pl}
     * @copyright NIE usuwaj tego komentarza! (Do NOT remove this comment!)
     */
    
    //////////////////// SETTINGS ////////////////////
    /**
     * Strona kodowa.
     * @global string $CHARSET
     */
    $CHARSET = 'utf-8';
    
    /**
     * Preferowana wersja DTD (XHTML 1.1, XHTML 1.0 Strict, XHTML 1.0 Transitional, XHTML 1.0 Frameset).
     * @global string $DTD
     */
    $DTD = 'XHTML 1.1';
    
    /**
     * Wersja DTD w przypadku braku pełnej interpretacji XHTML 1.1 (XHTML 1.0 Strict, XHTML 1.0 Transitional, XHTML 1.0 Frameset).
     * @global string $DTD2
     */
    $DTD2 = 'XHTML 1.0 Strict';
    
    /**
     * Czy brać pod uwagę typy MIME języka XML (true - tak, false - nie).
     * MOŻE SPOWODOWAĆ PROBLEMY Z WYŚWIETLENIEM DOKUMENTU!
     * @global bool $XML
     */
    $XML = false;
    
    /**
     * Arkusze CSS wraz z mediami (opcjonalnie).
     * Przykłady:
     * - 'style.css',
     * - 'style.css"all',
     * - 'style.css print.css"print'.
     * @global string $CSS
     */
    $CSS = '';
    //////////////////////////////////////////////////
    
    
    if (defined('CSS')) $CSS .= ' '.CSS;
    $CSS = trim($CSS);
    if ($CSS == '') $CSS = array();
    else
    {
    	$CSS = split(' +', $CSS);
    	foreach ($CSS as $i => $css) $CSS[$i] = explode('"', $css);
    }
    
    $MIME = 'text/html';
    if (array_key_exists('HTTP_ACCEPT', $_SERVER))
    {
    	if (preg_match_all('/application\/xhtml\+xml(?![+a-z])([^,]*;\s*q\s*=\s*([0-9.]+))?/i', $_SERVER['HTTP_ACCEPT'], $matches) && (count($matches) < 3 || $matches[2] > 0)) $MIME = 'application/xhtml+xml';
    	else if ($XML)
    	{
    		if (preg_match_all('/application\/xml(?![+a-z])([^,]*;\s*q\s*=\s*([0-9.]+))?/i', $_SERVER['HTTP_ACCEPT'], $matches) && (count($matches) < 3 || $matches[2] > 0)) $MIME = 'application/xml';
    		else if (preg_match_all('/text\/xml(?![+a-z])([^,]*;\s*q\s*=\s*([0-9.]+))?/i', $_SERVER['HTTP_ACCEPT'], $matches) && (count($matches) < 3 || $matches[2] > 0)) $MIME = 'text/xml';
    	}
    }
    else if (array_key_exists('HTTP_USER_AGENT', $_SERVER) && preg_match('/W3C[^a-z]Validator/i', $_SERVER['HTTP_USER_AGENT'])) $MIME = 'application/xhtml+xml';
    
    if ($MIME == 'text/html' && $DTD == 'XHTML 1.1') $DTD = $DTD2;
    
    header("Content-Type: $MIME; charset=$CHARSET");
    echo "<"."?xml version=\"1.0\" encoding=\"$CHARSET\"?".">\n";
    if ($MIME != 'text/html' || !array_key_exists('HTTP_USER_AGENT', $_SERVER) || !preg_match('/\sMSIE\s*([0-9])/', $_SERVER['HTTP_USER_AGENT'], $matches) || $matches[1] > 6) foreach ($CSS as $css) echo "<"."?xml-stylesheet href=\"".$css[0]."\" type=\"text/css\"".(empty($css[1]) ? "" : " media=\"".$css[1]."\"")."?".">\n";
    require_once dirname(__FILE__)."/$DTD.inc.php";
    echo "\n";
    if ($MIME == 'text/html')
    {
    	echo "<meta http-equiv=\"Content-Type\" content=\"text/html; charset=$CHARSET\">\n";
    	foreach ($CSS as $css) echo "<link rel=\"stylesheet\" href=\"".$css[0]."\" type=\"text/css\"".(empty($css[1]) ? "" : " media=\"".$css[1]."\"").">\n";
    }
    ?>
  2. W tym samym katalogu (mime) utwórz następujące pliki:
    • XHTML 1.1.inc.php
      <!DOCTYPE
      	html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
      	"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
      <html xmlns="http://www.w3.org/1999/xhtml">
      <head>
    • XHTML 1.0 Strict.inc.php
      <!DOCTYPE html 
      	PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
      	"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
      <html xmlns="http://www.w3.org/1999/xhtml" lang="pl">
      <head>
    • XHTML 1.0 Transitional.inc.php
      <!DOCTYPE html 
      	PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
      	"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
      <html xmlns="http://www.w3.org/1999/xhtml" lang="pl">
      <head>
    • XHTML 1.0 Frameset.inc.php
      <!DOCTYPE html 
      	PUBLIC "-//W3C//DTD XHTML 1.0 Frameset//EN"
      	"http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd">
      <html xmlns="http://www.w3.org/1999/xhtml" lang="pl">
      <head>
  3. Każdemu dokumentowi XHTML nadawaj rozszerzenie *.php, a nie *.html.
  4. Wszystkie dokumenty XHTML buduj w następujący sposób (na początku należy podać lokalizację utworzonego przed momentem pliku mime.inc.php):
    <?php require_once 'mime/mime.inc.php'; ?>
    <title>Tytuł dokumentu</title>
    </head>
    <body>
    
    <p>Treść dokumentu...</p>
    
    </body>
    </html>
    Natomiast, aby w określonym dokumencie lub kilku dokumentach wstawić dodatkowe arkusze stylów CSS - inne niż dla całości serwisu - użyj następującej składni:
    <?php
    // Dodatkowe arkusze CSS rozdzielone spacjami:
    define('CSS', 'css/style3.css css/style4.css');
    require_once 'mime/mime.inc.php';
    ?>
    <title>Tytuł dokumentu</title>
    </head>
    <body>
    
    <p>Treść dokumentu...</p>
    </body> </html>
    Można również podać media:
    <?php
    // Dodatkowe arkusze CSS rozdzielone spacjami:
    define('CSS', 'css/style.css css/print.css"print');
    require_once 'mime/mime.inc.php';
    ?>
    <title>Tytuł dokumentu</title>
    </head>
    <body>
    
    <p>Treść dokumentu...</p>
    </body> </html>

Jeżeli uda Ci się już przekonwertować wszystkie dokumenty do standardu XHTML i pomyślisz o wysyłaniu ich z typem MIME application/xhtml+xml, może zaskoczyć Cię pewien sposób zachowania przeglądarek (np. Netscape/Mozilla/Firefox, Opera, Chrome). Mianowicie żaden dokument XHTML przetwarzany zgodnie regułami języka XML (tzn. z typem MIME innym niż text/html) nie wyświetli się, jeżeli będzie zawierał błędy XML! Takim błędem może być np. przeplatanie znaczników:

<p>To jest przykład błędnego kodu XML: wewnątrz paragrafu jest <em>emfaza.</p></em>

Po wpisaniu takiego kodu, zamiast spodziewanej strony, ujrzymy komunikat błędu ze wskazaniem linii, w której on wystąpił. Pozornie takie działanie może być niewygodne, ale tak naprawdę to jest mechanizm, na który od dawna czekali bardziej zaawansowani webmasterzy. Dzięki niemu po prostu wszystkie poważne błędy składniowe mogą zostać wyeliminowane na wczesnym etapie. W dokumencie HTML (lub XHTML 1.0 z typem MIME text/html) taki błąd w ogóle nie dałby o sobie znać, a zatem najprawdopodobniej pozostałby niezauważony. Każda przeglądarka HTML stara się "korygować" tego typu pomyłki webmasterów tak, aby strona mogła się wyświetlić. Jednak nigdy nie ma pewności, że dany rodzaj błędu zostanie identycznie skorygowany w każdej możliwej przeglądarce, a co za tym idzie, strona może się wyświetlać na różne sposoby - niekoniecznie tak, jak w zamierzeniu życzył sobie tego autor.

Innym skutkiem używania typu MIME innego niż "text/html" jest zaprzestanie działania metody document.write(...) we wszystkich skryptach JavaScript osadzonych na stronie. Metoda ta została zaprojektowana do dynamicznego generowania całości lub części zawartości podczas ładowania dokumentu. Takie działanie jest wykluczone w języku XML, ponieważ dokumenty XML zawsze najpierw są parsowane, a dopiero potem renderowane. Obejściem tej niedogodności może być dynamiczne generowanie zawartości po załadowaniu, np. poprzez własności i metody zawarte w specyfikacji DOM. Zwykle możliwe jest także użycie nieustandaryzowanej właściwości innerHTML.