Share via


Kasper Mütze in XML oder: Eine Etüde über das Ü

Veröffentlicht: 09. Dez 2001 | Aktualisiert: 18. Jun 2004

Von Matthias Lohrer

Umlaute und Sonderzeichen entwickeln bei der Bearbeitung in XML und XSLT oft ein verwirrendes Eigenleben. Das ist um so merkwürdiger, als es offiziell gar keine Probleme mit Umlauten geben darf, da XML auf dem universellen Unicode basiert. Dieser Beitrag beleuchtet die Schwierigkeiten und zeigt, wie sie vermieden werden können.

Auf dieser Seite

 Ohne MSXML 3.0 geht es nicht
 Einfache Beispiele zum Üben
 UTF-8 versus ISO 8859-1
 Von XML nach HTML
 Die Übertragung nach XSLT
 Vom Ü zum Euro

Diesen Artikel können Sie hier lesen dank freundlicher Unterstützung der Zeitschrift:

Bild04

Wer bislang erst wenig Erfahrung mit XML sammeln konnte, wird sicherlich über die korrekte Verwendung der deutschen Umlaute und einiger oft benutzter Sonderzeichen stolpern. Jedenfalls entsteht dieser Eindruck, wenn man die gängigen XML-Newsgroups studiert. Immer wieder tauchen Fragen dazu auf, wie sich etwa die Umlaute in XML speichern lassen oder wie sich ein ü in HTML ausgeben lässt. Das geschützte Leerzeichen   widersetzt sich auch recht standhaft einer Verarbeitung in XML.

Das alles lässt sich vermeiden, allerdings ist dabei einiges zu beachten. Als Beispiel dient ein Adressverzeichnis, das in einem XML-Dokument gespeichert, mit Hilfe des MSXML3-Parsers verarbeitet und in einer HTML-Datei ausgegeben werden soll.

Ohne MSXML 3.0 geht es nicht

Als Entwicklungsumgebung für die im Folgenden beschriebenen Tests kommen Windows 2000 Professional und Word 2000 zum Einsatz. Als XML-Parser wird MSXML 3.0 verwendet. Da diese Version noch mit keinem Internet Explorer ausgeliefert wird, müssen Sie sie möglicherweise erst installieren. Sie finden die aktuelle Version auf der Heft-CD oder der XML-Webseite von Microsoft unter der Adresse http:// msdn.microsoft.com/xml. Im Unterschied zum alten MSXML 2.5 implementiert MSXML 3.0 nahezu vollständig die W3C-Standards XPath und XSLT.

Im VBA-Editor können Sie mit Hilfe des Document Object Models auf die XML-Daten zugreifen, wenn Sie einen Verweis auf die Objektbibliothek Microsoft XML, v3.0 setzen (die Bibliothek msxml3.dll findet sich im System 32-Verzeichnis von Windows). Die XML-Dateien erstellen Sie in Word und speichern sie im Format Nur Text.

 

Einfache Beispiele zum Üben

Um sich mit der Thematik vertraut zu machen, speichern Sie zunächst eine ganz einfache XML-Datei ohne Umlaute. Erstellen Sie die Datei freunde.xml (Listing 1).

Listing 1: Die Adressdatei im Minimalformat.

<?xml version="1.0"?> 
<!-- freunde.xml --> 
<Adressbuch> 
<Name>Kasper</Name> 
</Adressbuch>

Diese XML-Datei soll in VBA geladen und deren Inhalt mit Debug.Print testweise ausgegeben werden. Das erledigt die Routine Einlesen (Listing 2).

Listing 2: Die Prozedur gibt die Adressdatei aus.

Sub Einlesen() 
Dim xml As New DOMDocument 
xml.Load "L:\xml-umlaute\freunde.xml" 
If (xml.parseError <> 0) Then 
  If xml.parseError.reason <> "" Then 
    Debug.Print xml.parseError.reason 
  End If 
  Exit Sub 
End If 
Debug.Print xml.xml 
End Sub

Achten Sie auf den korrekten Pfad und darauf, dass ein Verweis auf die MSXML-Objektbibliothek (msxml.dll) gesetzt ist, da Sie sonst die Fehlermeldung Fehler beim Kompilieren. Benutzerdefinierter Typ nicht erlaubt. erhalten. Falls Ihnen beim Erzeugen der XML-Datei ein Fehler unterlaufen ist, wird die parseError-Eigenschaft entsprechend gesetzt und eine Fehlermeldung ausgegeben. Klappt hingegen alles, erscheint im geöffneten Direktfenster der Code des XML-Dokuments.

Um die Umlaute hinzuzunehmen, erhält der betreffende Herr einen Nachnamen. Er heißt jetzt nicht mehr nur Kasper, sondern Kasper Mütze. Beim erneuten Aufruf der Prozedur Einlesen erscheint prompt im Direktfenster die Fehlermeldung An invalid character was found in text content.

Das Problem ist schnell gelöst. XML versteht Deutsch, wenn Sie im XML-Prolog die passende Kodierung angeben.

Listing 3 zeigt die korrigierte XML-Datei.

Listing 3: Die Adressdatei mit einem Umlaut.

<?xml version="1.0" encoding="iso8859-1" ?> 
<!-- freunde.xml --> 
<Adressbuch> 
<Name>Kasper Mütze</Name> 
</Adressbuch>

Rufen Sie die Prozedur erneut auf, gibt sie Folgendes aus:

<?xml version="1.0"?> 
<!-- freunde.xml --> 
<Adressbuch> 
<Name>Kasper Mütze</Name> 
</Adressbuch>

Vergleichen Sie die Ausgabe mit Listing 3, werden Sie feststellen, dass der Zusatz encoding='iso8859-1' verschwunden ist.

Zu solchen Feinheiten der Kodierung findet sich im msdn online Web Workshop (https://msdn.microsoft.com/workshop/default.asp) ein instruktiver Artikel [1], der die Aussage enthält „This is normal." Weitere Erläuterungen gebe ich frei übersetzt wieder: Der String, den die xml-Eigenschaft zurückgibt, ist universal verwendbar. Er lässt sich beispielsweise auch an die LoadXML-Methode übergeben. Alles wird wie erwartet funktionieren. Wenn an dieser Stelle stattdessen der Hinweis auf encoding="iso8859-1" stünde, würde folgende Fehlermeldung erzeugt: Switch from current encoding to specified encoding not supported. Das bedeutet, dass die xml-Eigenschaft nicht den tatsächlichen Quellcode der XML-Datei wiedergibt, sondern den Code nur so kennt, wie ihn der Parser intern auffasst. Intern arbeitet der Parser jedoch generell nur auf der Basis von Unicode. Deswegen muss und darf hier kein expliziter Hinweis auf ein bestimmtes Encoding erfolgen.

Müssen Sie herausfinden, was tatsächlich in der Processing Instruction steht, dürfen Sie nicht die xml-Eigenschaft verwenden, sondern stattdessen die Text-Eigenschaft:

Debug.Print xml.firstChild.Text

Dann lautet die Ausgabe:

version="1.0" encoding="iso8859-1"

Hingegen gibt der folgende Befehl

Debug.Print xml.firstChild.xml

wie gehabt aus:

<?xml version="1.0"?>

Testweise können Sie nun die geladene XML-Datei mitsamt dem gefährlichen Umlaut in einer zweiten Datei speichern. Dazu ist nur eine weitere Zeile Code notwendig:

xml.Save ("L:\xml-umlaute\kopie.xml")

Fügen Sie folgende Zeile hinzu, erscheint im Direktfenster wieder die Ausgabe ohne den Encoding-Zusatz:

Debug.Print xml.xml

Die Datei selbst hat aber diesen Zusatz. Nehmen Sie das einfach hin. Wenn der Parser das automatisch so macht, soll es uns recht sein.

Zum Abschluss dieser Einstiegsrunde versuchen Sie jetzt noch, ein komplettes XML-Dokument innerhalb einer Prozedur von Grund auf neu aufzubauen und zu speichern (Listing 4).

Listing 4: Die Prozedur erzeugt ein XML-Dokument.

Sub Neu() 
Dim xml As New DOMDocument 
Dim e As IXMLDOMElement 
xml.loadXML "<Adressbuch/>" 
Set e = xml.createElement("Name") 
e.Text = "Kasper Mütze" 
xml.documentElement.appendChild e 
xml.Save "L:\xml-umlaute\neu.xml" 
Debug.Print xml.xml 
End Sub

Mit loadXML können Sie ein XML-Dokument auf der Basis eines einfachen Strings erstellen. Zunächst speichern Sie hier nur das leere Element <Adressbuch/> und fügen anschließend ein Element <Name> mit dem Text Kasper Mütze hinzu. Debug.Print gibt Folgendes aus:

<Adressbuch><Name>Kasper Mütze</Name></Adressbuch>

Aber die Datei hat ein Problem, das Sie in Bild 1 sehen können. Bevor das Rätsel gelöst wird, erweitern Sie den Code um vier Zeilen:

Set xml = Nothing 
Set xml = New DOMDocument  
xml.Load "L:\xml-umlaute\neu.xml" 
Debug.Print xml.xml

Sie bewirken, dass nach dem Speichern die Datei erneut geladen und deren Inhalt mit Debug.Print ausgegeben wird.

Bild01

Bild 1

 

UTF-8 versus ISO 8859-1

Mütze ist Mütze in UTF-8-Formatierung. Die Save-Methode speichert die Daten standardmäßig im UTF-8-Format, das so etwas wie Unicode in Kurzform ist. Word erkennt aber das UTF-8-Format nicht automatisch, sondern interpretiert die XML-Datei so, als wenn sie im ISO-8859-1-Format vorliegen würde. Daraus resultiert die Anzeige Mütze.

Word 2000 kann aber auch UTF-8-Dateien korrekt anzeigen, wenn Sie Folgendes tun:

  • Aktivieren Sie im Dialog Optionen auf der Registerkarte Allgemein das Feld Konvertierung beim Öffnen bestätigen.

  • Öffnen Sie die XML-Datei erneut. Es erscheint der Dialog Datei konvertieren.

  • Geben Sie als Format der Datei Codierter Text an.

  • Im Folgedialog geben Sie im Feld Andere Codierung UTF-8 an. Anschließend erscheint bereits in der Vorschau der gewünschte Text Mütze, der auch nach dem Öffnen erhalten bleibt.

Die Methoden Save und Load verarbeiten Daten standardmäßig im UTF-8-Format. Wenn Sie möchten, können Sie Ihre XML-Dateien auch in diesem Format erstellen. Sie benötigen dazu nur einen Editor, der mit diesem Format umgehen kann. Möchten Sie lieber einen Editor verwenden, der nicht mit UTF-8 umgehen kann, müssen Sie dem Parser irgendwie mitteilen, dass die Daten nicht im UTF-8-Format vorliegen, sondern beispielsweise im üblichen ISO-8859-1-Format. Genau das wird im XML-Prolog mit der Angabe zur Zeichencodierung erledigt.

Als Nächstes stellt sich die Frage, ob der Parser XML-Daten im ISO-8859-1-Format nicht nur lesen, sondern auch schreiben kann. Die Antwort lautet Ja, wenn das Dokument im XML-Prolog über einen entsprechenden Encoding-Eintrag verfügt.

Listing 5: Die Prozedur erzeugt eine XML-Datei und speichert sie im ISO-8859-1-Format.

Sub NeuInIso88591a() 
Dim xml As New DOMDocument 
Dim e As IXMLDOMElement 
xml.loadXML "<?xml version='1.0' encoding='iso-8859-1'?><Adressbuch/>" 
Set e = xml.createElement("Name") 
e.Text = "Kasper Mütze" 
xml.documentElement.appendChild e 
xml.Save "L:\xml-umlaute\neu-iso.xml" 
Debug.Print xml.xml 
End Sub

Listing 5 zeigt, wie es geht. Der Methode loadXML wird die Processing Instruction gleich mit übergeben. Debug.Print gibt Folgendes aus:

<?xml version="1.0"?> 
<Adressbuch><Name>Kasper Mütze</Name></Adressbuch>

Die Datei neu-iso.xml sieht so aus:

<?xml version="1.0" encoding="iso-8859-1"?> 
<Adressbuch><Name>Kasper Mütze</Name></Adressbuch>

Weiter oben wurde bereits erläutert, warum bei der Ausgabe mit Hilfe von Debug.Print der Hinweis encoding="iso-8859-1" fehlt. Die Datei selbst enthält hingegen den kompletten XML-Prolog mit der Angabe zur Codierung und im Text steht das gefährliche Ü.

Alternativ können Sie im Quellcode die Processing Instruction auch als Knoten erzeugen und mit appendChild anfügen. Das geschieht in Listing 6. Sie müssen lediglich darauf achten, dass die Processing Instruction ganz am Anfang der Datei steht.

Listing 6: Die Prozedur setzt mehrere XML-Knoten zu einem XML-Dokument zusammen.

Sub NeuInIso88591b() 
Dim xml As New DOMDocument 
Dim e1 As IXMLDOMElement 
Dim e2 As IXMLDOMElement 
Dim pi As IXMLDOMProcessingInstruction 
Set pi = xml.createProcessingInstruction("xml", "version = '1.0' encoding = 'iso-8859-1'") 
Set e1 = xml.createElement("Adressbuch") 
Set e2 = xml.createElement("Name") 
e2.Text = "Kasper Mütze" 
e1.appendChild e2 
xml.appendChild pi 
xml.appendChild e1 
xml.Save "L:\xml-umlaute\neu-iso2.xml" 
Debug.Print xml.xml 
End Sub

Die Save-Methode orientiert sich an der XML-Deklaration. Wenn Sie innerhalb des Quellcodes herausfinden müssen, welche Zeichencodierung gerade aktuell ist, können Sie die bereits erwähnte Text-Eigenschaft des Processing-Instruction-Knotens mit dem XML-Prolog verwenden. Dann wissen Sie, ob Save eine UTF-8- oder beispielsweise eine ISO-8859-1-Datei erzeugen wird.

Bevor es um die Konvertierung in HTML geht, soll ein weiterer interessanter Irrweg kurz erwähnt werden. Wenn Ihnen noch nicht bekannt wäre, dass sich die Umlaute nur dann in XML speichern lassen, wenn der XML-Prolog die entsprechende Encoding-Angabe enthält, könnten Sie auf die Idee kommen, statt Mütze das Wort M&uuml;tze zu speichern. Probieren Sie es aus, entdeckt der Parser einen Fehler, den Debug.Print ausgibt:

Reference to undefined entity 'uuml'.

XML kennt von Haus aus nur fünf so genannte Entitäten, also Ausdrücke, die mit & anfangen und mit einem Semikolon enden:

  • &amp; (&)

  • &< (<)

  • &> (>)

  • &apos; (')

  • " (")

Sie können sie jederzeit in Ihren XML-Dokumenten verwenden. Wenn Sie möchten, können Sie außerdem eigene Entitäten in der DTD definieren. Ohne DTD geht das jedoch nicht, was einige Nachteile mit sich bringt. Eine DTD kann nämlich nicht nur aus der Definition von Entitäten bestehen, sondern muss die gesamte Dokumentstruktur festlegen, ein nicht unerheblicher Mehraufwand. Speichern Sie doch lieber gleich ein ü, als erst Verrenkungen für &uuml; machen zu müssen.

 

Von XML nach HTML

Kasper Mütze steht also endlich in Ihrem XML-Adressbuch. Möchten Sie es im Internet zur Verfügung stellen, müssen Sie Kasper Mütze in einem HTML-Dokument ausgeben. Zum Erzeugen verwenden Sie XSLT, das in MSXML 3.0 dem W3C-Standard entsprechend implementiert ist.

Auf der HTML-Seite sollen die Namen untereinander stehen. Listing 7 zeigt das HTML-Dokument.

Listing 7: Das Adressbuch als HTML-Seite, erster Versuch.

<html><head><title>Meine Freunde</title></head> 
<body> 
<h1>Meine Freunde</h1> 
<ul> 
<li>Kasper M&uuml;tze</li> 
<li>mein zweiter Freund</li> 
<li>usw.</li> 
</ul> 
</body> 
</html>

Die Daten haben Sie bereits in der XML-Datei gesammelt. Nun benötigen Sie eine XSLT-Datei, die die XML-Daten in das gewünschte HTML-Format umwandelt. Das erledigt die Prozedur Freunde (Listing 9). Listing 8 zeigt den ersten Entwurf für die XSLT-Datei, Listing 10 die Ausgabe. In Bild 2 sehen Sie, wie der Browser das Ergebnis darstellt.

Bild02

Bild 2

Listing 8: Die XSLT-Datei zur Transformation in HTML, erster Versuch.

<?xml version="1.0" encoding="iso-8859-1"?> 
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> 
<xsl:template match="/"> 
<html><head><title>Meine Freunde</title></head> 
<body> 
<h1>Meine Freunde</h1> 
<ul> 
<xsl:for-each select="//Name"> 
<li><xsl:value-of select="." /></li> 
</xsl:for-each> 
</ul> 
</body> 
</html> 
</xsl:template> 
</xsl:stylesheet>

Listing 9: Die Prozedur wandelt ein XML- in ein HTML-Dokument um.

Sub freunde() 
Dim xmldatei As String 
Dim xsltdatei As String 
Dim xml As New DOMDocument 
Dim xsl As New DOMDocument 
Dim html As String 
xmldatei = "L:\xml-umlaute\freunde.xml" 
xsltdatei = "L:\xml-umlaute\freunde.xsl" 
xml.Load xmldatei 
If (xml.parseError <> 0) Then 
  If xml.parseError.reason <> "" Then 
    Debug.Print xml.parseError.reason 
    Debug.Print xml.parseError.Line 
  End If 
  Exit Sub 
End If 
xsl.Load xsltdatei 
If (xsl.parseError <> 0) Then 
  If xsl.parseError.reason <> "" Then 
    Debug.Print xsl.parseError.reason 
    Debug.Print xsl.parseError.Line 
  End If 
  Exit Sub 
End If 
html = xml.transformNode(xsl) 
Debug.Print html 
End Sub

Listing 10: Ausgabe der ersten Umwandlung.

<html><head> 
<META http-equiv="Content-Type" content="text/html; charset=UTF-16"> 
<title>Meine Freunde</title></head> 
<body> 
<h1>Meine Freunde</h1> 
<ul> 
<li>Kasper Mütze</li> 
</ul> 
</body> 
</html>

Unter einem Kasper M?? kann sich aber niemand etwas vorstellen. Eigentlich müsste da ja auch M&uuml;tze statt Mütze stehen. Wie aber können Sie XML/XSLT beibringen, aus dem ü ein &uuml; zu machen?

Es gibt zwar Mittel und Wege, dieses &uuml; im Zieldokument zu erzeugen, aber der Aufwand dafür lohnt sich einfach nicht. Bedenken Sie: Sie wollen doch gar nicht unbedingt ein &uuml; im HTML-Dokument haben, sondern Sie wollen, dass der Browser ein Ü darstellt. Früher ging das nur mit &uuml;. Inzwischen reicht ein META-Tag im Header der HTML-Datei:

<META http-equiv="Content-Type" content="text/html; charset=iso-8859-1">

Sicher erkennen Sie das vertraute iso-8859-1 wieder. Modifizieren Sie die HTML-Datei entsprechend, werden Sie sehen, dass das Ü korrekt dargestellt wird.

 

Die Übertragung nach XSLT

Zunächst einmal fällt auf, dass bei der XSLT-Transformation in das HTML-Dokument ein META-Tag eingefügt wird, ohne dass Sie selbst im XSLT-Dokument eine entsprechende Angabe gemacht haben. Wie kommt es dazu und wie können Sie erreichen, dass die Angabe iso-8859-1 berücksichtigt wird?

An dieser Stelle kommt ein XSLT-Element ins Spiel, das in der aktuellen XSLT-Datei noch nicht auftaucht, das aber bereits im Hintergrund sein Wesen oder Unwesen treibt: xsl:output.

Die jetzige Ausgabe ist identisch mit derjenigen, die entstanden wäre, wenn direkt hinter dem xsl:stylesheet-Element dieses Element stünde:

<xsl:output method="html" encoding="UTF-16" />

Für method stehen die Werte html, xml und text zur Verfügung. Verwenden Sie text, werden nur die Angaben zwischen den Tags ausgegeben. xml erzeugt ein neues XML-Dokument, html ein HTML-Dokument, allerdings mit ein paar Besonderheiten. Eine dieser Besonderheiten ist das Einfügen eines META-Tags im HTML-Header. Die W3C-Dokumentation legt im Abschnitt 16.2 zur HTML Output Method fest:

The encoding attribute specifies the preferred encoding to be used. If there is a HEAD element, then the html output method should add a META element immediately after the start-tag of the HEAD element specifying the character encoding actually used. [2]

Die Methode html wird übrigens standardmäßig verwendet, wenn im XSLT-Dokument der Root-Tag <html> auftaucht. Es scheint also eine einfache Lösung zu geben. Probieren Sie es aus, indem Sie in der XSLT-Datei folgenden Eintrag ergänzen:

<xsl:output method="html" encoding="iso-8859-1" />

Als Ergebnis erhalten Sie in der HTML-Datei diesen META-Tag:

<META http-equiv="Content-Type" content="text/html; charset=UTF-16">

Ich habe keine Erklärung für dieses Verhalten und warte darauf, den betreffenden Artikel bei Microsoft zu finden, der auch hier sagt „This is normal." It's not a bug, it's a feature. Ich vermute, dass der Grund ähnlich wie bei der xml-Eigenschaft darin liegt, dass nicht die definierte, sondern die aktuell eingesetzte Codierung verwendet wird, und das ist eben Unicode. Intern arbeitet MSXML 3.0 mit COM-Strings, die per definitionem UTF-16 verwenden.
In der Zwischenzeit müssen Sie sich anders behelfen, und zwar so:

  • Verwenden Sie nicht die output-Methode html, sondern xml.

  • Verwenden Sie im xsl:output-Element das Attribut omit-xml-declaration="yes".

  • Wenn Sie zusätzlich das Attribut indent="yes" einfügen, wird der Ausgabetext übersichtlich umbrochen.

  • Schreiben Sie den gewünschten META-Tag immer selbst in die XSLT-Datei.

Listing 11 enthält die angepasste XSLT-Datei.

Listing 11: Die korrigierte XSLT-Datei.

<?xml version="1.0" encoding="iso-8859-1"?> 
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> 
<xsl:output method="xml" encoding="iso-8859-1" omit-xml-declaration="yes" indent="yes" /> 
<xsl:template match="/"> 
<html><head><meta http-equiv="content-type" content="text/html; charset=iso-8859-1"/> 
<title>Meine Freunde</title></head> 
<body> 
<h1>Meine Freunde</h1> 
<ul> 
<xsl:for-each select="//Name"> 
<li><xsl:value-of select="." /></li> 
</xsl:for-each> 
</ul> 
</body> 
</html> 
</xsl:template> 
</xsl:stylesheet>

Und damit lautet das Ergebnis endlich so, wie es Listing 12 und Bild 3 zeigen.

Listing 12: Die korrigierte HTML-Datei.

<html><head><meta http-equiv="content-type" content="text/html; charset=iso-8859-1" /> 
<title>Meine Freunde</title></head> 
<body> 
<h1>Meine Freunde</h1> 
<ul> 
<li>Kasper Mütze</li> 
</ul> 
</body> 
</html>

Bild03

Bild 3

 

Vom Ü zum Euro

Zum Abschluss möchte ich Ihnen noch einige Tipps geben, um Ihnen weitere, typische Stolperfallen zu ersparen.

Dazu gehört das &nbsp;, das in Tabellen beispielsweise dafür sorgt, dass leere Zellen nicht wirklich leer sind, weil ja wenigstens ein non-breakable-space enthalten ist. Wie können Sie ein &nbsp; im HTML-Code erzeugen? Sie ahnen schon die Antwort: Lassen Sie es bleiben! Verwenden Sie statt dessen &#160;. Das hat den gleichen Effekt und verursacht keinerlei Schwierigkeiten. Das resultierende Leerzeichen sieht im HTML-Text später so aus wie ein gewöhnliches Leerzeichen, hat aber genau den gewünschten Non-breaking-Effekt.

Sie haben auch die Möglichkeit, das geschützte Leerzeichen in der XML- oder XSLT-Datei über den numerischen Ziffernblock ([Alt]+[255]) einzugeben. Warum [Alt]+[255] ausgerechnet das Zeichen mit dem Code 160 erzeugt, weiß ich nicht. Es muss etwas damit zu tun haben, dass hier eine andere Codierung fest verdrahtet ist. Der Nachteil besteht allerdings darin, dass Sie im Code selbst nicht mehr erkennen können, ob ein Leerzeichen geschützt oder nicht geschützt ist. Daher ist das ausgeschriebene &#160; aussagekräftiger.

Für alle Zeichen, die Bestandteil des ISO-8859-1-Zeichensatzes sind, gilt im Übrigen, dass Sie sie wörtlich hinschreiben können. Schreiben Sie also nicht &copy;, sondern verwenden Sie einfach das ©-Zeichen.

Außerdem funktioniert immer die Angabe einer numerischen Entität. Das ©-Zeichen ließe sich also genauso mit &#169; angeben, weil es im Zeichensatz genau an dieser Stelle steht.

Ein Zeichen, das Sie in Zukunft oft verwenden werden, das aber nicht Bestandteil von ISO-8859-1 ist, ist das Euro-Zeichen. Dafür können Sie die numerische Entität &#8364; oder das hexadezimale Äquivalent &#x20AC; verwenden. Kennen Sie den entsprechenden Unicode-Code, können Sie im Prinzip jedes Zeichen ausgeben, das Bestandteil von Unicode ist – vorausgesetzt, dass der Browser dieses Zeichen auch darstellen kann. Unter www.unicode.org finden Sie hierzu genauere Informationen [3].

Zum Ausklang nun noch eine letzte Dissonanz zum Thema Transformierung nach HTML. Sie könnten vielleicht auf die Idee kommen, statt der Methode transformNode die Methode transformNodeToObject zu verwenden. Das Ergebnis der Transformation wird dabei nicht in einem String, sondern in einem eigenen DOM-Objekt abgelegt. Das heißt auch, dass das Ergebnis selbst ein gültiges XML-Dokument sein muss. Genau daran scheitert der Aufruf dieser Methode, denn entsprechend dem W3C-Standard wird der automatisch eingefügte META-Tag nicht mit einem schließenden Tag geschlossen.

Ich finde das bemerkenswert: Um HTML-Dateien zu erzeugen, dürfen Sie auf keinen Fall die output-Methode html verwenden. Sie können also beinahe froh sein, dass es überhaupt möglich ist, XML in HTML umzuformen.

[1] Chris Lovett; How to Encode XML Data; https://msdn.microsoft.com/xml/articles/ xmlencodings.asp
[2] Unicodezeichen finden Sie unter: http://www.unicode.org/charts
[3] XSL Transformations (XSLT) Version 1.0, W3C Recommendation 16 November 1999: http://www.w3.org/TR/xslt