Hallo,
ich verstehe nicht wieso das Zeichen "<" in einem Tag-Attribut nicht erlaubt ist.
So doof es klingt, eine bessere Antwort als mein Betreff kann es darauf nicht geben.
Ich versuche das mal anhand der Standards zu erklären:
Laut Definition bestehen wohlgeformte XML-Dokumente aus Markup und Text. Lass Dich nicht durch das ständige Reden von Entities in der XML-Spezifikation verwirren, das bezieht sich nur aufs Parsen, die physikalische Ebene. Markup und Text ist dann die logische Ebene. Meiner Meinung nach trägt diese sicherlich wichtige Unterscheidung stark zur Schwierigkeit des Lesens der XML-Spec bei. Bleiben wir auf der logischen Ebene.
Laut einer weiteren Definition besteht Markup aus diversen Zeugs:
„Markup takes the form of start-tags, end-tags, empty-element tags, entity
references, character references, comments, CDATA section delimiters,
document type declarations, processing instructions, XML declarations,
text declarations, and any white space that is at the top level of the
document entity“
Markup ist also mehr als das am häufigsten verwendete <tag>inhalt</tag>. Weiter im Test steht da auch:
„The ampersand character (&) and the left angle bracket (<) MUST NOT
appear in their literal form, except when used as markup delimiters [...]“
Wir lernen: XML besteht aus Markup (und Text) und dieses unterschiedliche Markup erkennt man immer daran, dass es mit dem „start delimiter“ "<" beginnt (und je nach Art des Markups anders endet, aber doch mit einem ">"). Markup ist hier der entscheidende Begriff. Zwei Formen von Markup interessieren uns hier besonders.
Zum einen Processing Instructions, die sehen so aus:
<?target inhalt?>
„target“ ist hier die Bezeichnung für den Prozessor, der die PI ausführen soll. Ja, das ist die Syntax, die PHP für eine seiner Tags gewählt hat.
Ein ganz anderes Markup sind Start-Tags (<tag>), End-Tags (</tag>) und Empty-Element-Tags (<tag/>). Start- und End-Tags dürfen Attribute beinhalten. Attribute sind streng genommen Abbildungen von einem Namen auf einen Wert. Und der Wert besteht bitte nur aus Text und nicht aus Markup, denn der Wert ist Teil von Markup.
Ok, das ist ganz viel formale Definition, nur um zu sagen, was Du schon weisst, in Werten von Attributen darf kein Markup enthalten sein, Attribute sind Teil des Markups. Noch da? ;)
Die XML-Spezifikation ist in Sachen Intentionen eher mau. Aber Du hast mitgekriegt, es gibt eine physikalische und eine logische Ebene, XML zu betrachten. Auf der logischen Ebene gibt es diese Regeln für Markup, das wirkt sich dann auf die physikalische Ebene aus. Die physikalische und die logische Ebene kriegt XML aber nicht aus dem blauen Dunst. XML ist ein vereinfachtes SGML. XML-Dokumente sind demzufolge auch SGML-Dokumente. Und all die Definitionen und Intentionen erbt XML sozusagen von SGML. Also gucken wir dort mal nach.
(Ich zitiere hier mal überwiegend aus Anhang B des (nicht so frei verfügbaren) SGML-Standards, weil dort freundlicherweise richtiger Text steht)
SGML besteht aus Markup und Text:
„In generalized markup, the term “document” does not refer to a physical construct such as a file or a
set of printed pages. Instead, a document is a logical construct that contains a document element, the
top node of a tree of elements that make up the document’s content.
[...]
The elements are distinguished from one another by additional information, called markup, that is added
to the data content. A document thus consists of two kinds of information: data and markup.“
Markup kann aus verschiedenen Dingen bestehen:
„Markup is text that is added to the data of a document in order to convey information about it. In
SGML, the markup in a document fails into four categories:
a) Descriptive Markup (“Tags”) [...]
b) Entity Reference [...]
c) Markup Declaration [...]
d) Processing Instructions [...]“
Unter anderem auch aus PIs.
Deskriptives Markup kann Attribute enthalten:
„A descriptive tag normally includes the element’s generic identifier (Gl)
and may include attributes as well.“
Attribute bestehen nur aus Zeichen, nicht aus Markup:
„The value of an attribute consists of data characters and entity references, bounded by delimiters
called “literal delimiters” (lit), which are normally quotation marks (“).“
Wir haben nicht viel gelernt, ausser, dass es in SGML wie in XML ist. Warum nehmen die Autoren von SGML die PIs nicht ernst und erlauben die überall im Inhalt?
Guck Dir mal eine Templatesprache wie Mason an, z.B. hier. Du siehst Text, in den Perl Code eingebettet ist. In etwa ist der Perl Code hier Processing Instructions, Anweisungen, die beim Verarbeiten des Dokumentes ausgeführt werden sollen. Simplifiziert kann man diese Perl-PIs überall im ansonsten unstrukturierten Text einbetten. Hier sind PIs Elemente erster Klasse, alles andere ist nur zweitrangig. Man nennt diesen Stil auch Prozedurales Markup. Markup, dass sich auf die Verarbeitung auswirkt. Markup, das sagt: Tue dies, tue das.
Das kann toll sein, hat aber auch seine Nachteile. Man ist auf einen Interpreter für genau diese PIs angewiesen, im Falle von Mason Perl. Und man kann das Dokument nicht als Struktur behandeln, denn der Text ist im schlimmsten Fall unstrukturiert. Man kann das Dokument es im Prinzip nicht anders verarbeiten, denn es stehen lauter „Tue dieses“ drin, wenn man doch lieber „Tue jenes“ machen will. Und Programmlogik und Daten sind miteinander verflochten.
Das führte dazu, dass in solchen prozeduralen Sprachen abstrahiert wurde. Es wurde nicht mehr „Tue das“ gesagt, sondern abstrahiert „Dies ist etwas“ gesagt. Anfangs geschah das noch durch Makros. Der Sprung von TeX auf LaTeX ist so ein Beispiel. TeX ist eine Makrosprache in der man sagt „Formatiere dies bitte groß und fett“, in LaTeX sagt man „Dies ist eine Überschrift“. Letztendlich landet man dann bei deklarativen Markup. Prozedurales Markup sagt „Tue etwas“, deklaratives Markup sagt: „Das hier ist etwas“. Bei letzterem liegt die Verarbeitung also ausserhalb des Inhaltes, jenseits der Daten. Dafür haben die Daten eine Struktur. Konsequenterweise gibt es keine PIs mehr oder sie sind nicht mehr so mächtig wie
Aus dieser Evolution heraus ist auch SGML entstanden, es sollte größtenteils rein deklaratives Markup sein. Aus Abschnitt 0.1 Background des SGML Standards:
„Descriptive markup predominates and is distinguished from processing instructions.“
PIs gibt es zwar noch, aber sie sind nicht mehr universal überall einsetzbar. Aus Abschnitt 0.2 Objectives:
„Special delimiters for processing instructions to distinguish them from descriptive markup.
Processing instructions can be entered when needed for situations that cannot be handled by
the procedures, but they can easily be found and modified later when a document is sent to a
different processing system.“
Tatsächlich macht SGML im Gegensatz zu früheren Varianten klar, dass sie sich nicht um PIs kümmern, also auch weder interne Syntax noch Semantik dafür definieren. PIs sind nicht mehr integraler Bestandteil eines SGML Prozessors sondern etwas, dass extern und programmspezifisch ist. Es gib höchstens noch eine Syntax dafür. Tatsächlich rät der SGML Standard von PIs ab, aus Abschnitt 8, Processing Instructions:
„Processing instructions are deprecated, as they reduce portability of the document.“
Meinem Empfinden nach behandelt der SGML Standard PIs als Markup zweiter Klasse: „Wenn es unbedingt sein muss, dann gibt es halt noch PIs, aber Hauptsache sie verkomplizieren nichts und stören unsere Kre.. unser kostbares deklaratives Markup nicht. Denn für letzteres sind wir eigentlich hier.“
Ich denke aus dieser Überlegung kommt auch die Syntax für PIs. Denn wären PIs überall erlaubt, müsste man sie großartig komplizieren, eine PI in einem Attribut darf z.B. nur erlaubte Zeichenketten für Attributwerte zurückgeben, etc. Wozu, wenn man doch einen Standard für deklaratives Markup erstellen will? Also wurden PIs auf so „unwichtiges Markup“ zurückgestuft wie Kommentare. PIs sind in deklarativen Markup gar nicht vorhanden oder eben Anweisungen zweiter Klasse, wenn man sich nicht stark darum bemüht.
PHP hat nun für eine Variante der Einbindung die Form der PI gewählt. Ob aus Absicht oder aus Unwissen sei mal dahingestellt, Absicht liegt nahe, weil PHP meistens HTML ausspuckt und HTML eine SGML-Anwendung ist. Allerdings gibt es da einen Konflikt, PHP will eine möglichst mächtige Sprache sein und alles verändern können, schließlich ist es eine Programmiersprache. SGML dadurch aus XML haben aber ihren PIs Beschränkungen auf der logischen Ebene (Elemente mit Tags und Attributen) auferlegt.
Konsequenterweise behandelt PHP den Inhalt nicht auf der logischen sondern nur auf der physikalischen Ebene, auf der Textebene. Dadurch, dass es sich nicht um die logische Ebene kümmern wird es mächtiger, es kann jedes andere Textformat verarbeiten, es kann aber auch die logische Ebene von SGML bzw. XML nicht wohlgeformt bis invalide machen. PHPs PIs sind also rein zufällig ähnlich den PIs von SGML/XML, tragen aber aber die nicht gleiche Bedeutung, denn PHP verarbeitet prozedurales Markup, nicht deklaratives.
Deswegen bleiben Versuche, das deklarative Markup von SGML/XML mit prozeduralem Markup auszustatten und dennoch bei wohlgeformten, verarbeitbaren, evtl. sogar validen XML zu bleiben, nicht bei den PIs von SGML/XML selber. Stattdessen erfinden sie meist neue XML-Dialekte. Beispiele dafür sind eigene Elemente wie z.B. template:ifcondition oder Attribute in einem eigenen Namensraum wie z.B. die pythonische Templatesprache Kid bzw. dessen inoffizieller Nachfolger Genshi. Die in SGML und XML eingebauten PIs sind nämlich per Definition nicht mächtig genug.
Denn schließlich: SGML bzw. XML sollen nur deklaratives Markup beschreiben.
Tim