Funktionieren die bisher beschriebenen Tests auch mit Inhalten, die nicht ISO-8859-1 sind, beispielsweise mit russischen, griechischen oder chinesischen Texten und Metadaten?
Eine schwierige Frage. Denn auch wenn bei der Entwicklung von PDFUnit viel Wert darauf gelegt wurde, generell mit Unicode zu funktionieren, kann eine pauschale Antwort nur gegeben werden, wenn die eigenen Tests für PDFUnit selber mit „allen“ Möglichkeiten durchgetestet wurde. PDFUnit hat zwar etliche Tests für griechische, russische und chinesische Dokumente, aber es fehlen noch Tests mit hebräischen und japanischen PDF-Dokumenten. Insofern kann die eingangs gestellte Frage nicht abschließend beantwortet werden.
Prinzipiell tun Sie gut daran, sämtliche Werkzeuge auf UTF-8 zu konfigurieren, wenn Sie Unicode-Daten verarbeiten müssen.
Die folgenden Tipps im Umgang mit UTF-8 Dateien lösen nicht nur Probleme im Zusammenhang mit PDFUnit. Sie sind sicher auch in anderen Situationen hilfreich.
Metadaten und Schlüsselwörter können Unicode-Zeichen enthalten.
Wenn Ihre Entwicklungsumgebung die fremden Fonts nicht unterstützt, können
Sie ein Unicode-Zeichen mit \uXXXX
schreiben, wie
hier das Copyright-Zeichen „©“ als \u00A9
:
<testcase name="hasProducer_CopyrightAsUnicode"> <assertThat testDocument="unicode/unicode_producer.pdf"> <hasProducer> <!-- 'copyright' --> <matchingComplete>txt2pdf v7.3 \u00A9 SANFACE Software 2004</matchingComplete> </hasProducer> </assertThat> </testcase>
Es wäre nun zu mühsam, für längere Texte den Hex-Code aller Buchstaben
herauszufinden. Deshalb stellt PDFUnit das kleine Programm
ConvertUnicodeToHex
zur Verfügung.
Übergeben Sie den ausländischen Text als String an das Werkzeug,
entnehmen Sie der daraus erzeugten Datei anschließend den Hex-Code und fügen
ihn in Ihr Testprogramm ein. Eine genaue Beschreibung steht in Kapitel
9.12: „Unicode-Texte in Hex-Code umwandeln“.
Das Test mit Unicode sieht dann so aus:
<testcase name="hasSubject_Greek"> <assertThat testDocument="unicode/unicode_subject.pdf"> <hasSubject> <matchingComplete> Εργαστήριο Μηχανικής ΙΙ ΤΕΙ ΠΕΙΡΑΙΑ / Μηχανολόγοι </matchingComplete> </hasSubject> </assertThat> </testcase>
XML- und XPath-basierte Tests funktionieren auch mit Dateien, die Unicode enthalten, wie z.B. die nach XML extrahierten Bookmarks im folgenden Beispiel:
<!-- This test needs the following setting before starting ANT: set JAVA_TOOL_OPTIONS=-Dfile.encoding=UTF-8 --> <testcase name="hasBookmarks_MatchingXML"> <assertThat testDocument="unicode/unicode_bookmarks.pdf"> <hasBookmarks> <matchingXML file="unicode/unicode_bookmarks.xml" /> </hasBookmarks> </assertThat> </testcase>
In Kapitel 8: „XPath-Einsatz“ wird beschrieben, wie PDFUnit-Tests zusammen mit XPath funktionieren. Auch die XPath-Ausdrücke können Unicode enthalten:
<testcase name="hasBookmarks_MatchingXPath"> <assertThat testDocument="unicode/unicode_bookmarks.pdf"> <hasBookmarks> <!-- The line is wrapped for printing: --> <matchingXPath expr="//Title[@Action][.='\u00D1\u00EE\u00E4 \u00E5p\u00E6\u00E0 \u00ED\u00E8\u00E5']" /> </hasBookmarks> </assertThat> </testcase>
Jedes Java-Programm, das Dateien verarbeitet, also auch PDFUnit,
ist von der Umgebungsvariablen file.encoding
abhängig.
Es gibt mehrere Möglichkeiten, diese Umgebungsvariable für den jeweiligen
Java-Prozess zu setzen:
set _JAVA_OPTIONS=-Dfile.encoding=UTF8 set _JAVA_OPTIONS=-Dfile.encoding=UTF-8 java -Dfile.encoding=UTF8 java -Dfile.encoding=UTF-8
Während der Entwicklung von PDFUnit gab es zwei Tests, die unter Eclipse fehlerfrei liefen, unter ANT
aber mit einem Encoding-Fehler abbrachen. Die Ursache lag in der Java-System-Property
file.encoding
, die in der DOS-Box nicht auf UTF-8
stand.
Der folgende Befehl löste das Encoding-Problem unter ANT nicht:
// does not work for ANT: ant -Dfile.encoding=UTF-8
Statt dessen wurde die Property so gesetzt, wie im vorhergehenden Abschnitt für Shell-Skripte beschrieben:
// Used when developing PDFUnit: set JAVA_TOOL_OPTIONS=-Dfile.encoding=UTF-8
Wenn Sie XML-Dateien in Eclipse erstellen, ist es nicht unbedingt nötig, Eclipse auf UTF-8 einzurichten, denn XML-Dateien sind auf UTF-8 voreingestellt. Für andere Dateitypen ist aber die Codepage des Betriebssystems voreingestellt. Sie sollten daher, wenn Sie mit Unicode-Daten arbeiten, das Default-Encoding für den gesamten Workspace auf UTF-8 einstellen:
Abweichend von dieser Standardeinstellung können einzelne Dateien in einem anderen Encoding gepeichert werden.
Wenn Tests fehlschlagen, die auf Unicode-Inhalte testen, kann es sein, dass Eclipse oder ein Browser die Fehlermeldung nicht ordentlich dargestellen. Ausschlaggebend dafür ist das File-Encoding der Ausgabe, das von PDFUnit selber nicht beeinflusst werden kann. Wenn Sie in ANT dafür gesorgt haben, dass „UTF-8“ als Codepage verwendet wird, sind die meisten Probleme beseitigt. Danach können noch Zeichen aus der Codepage „UTF-16“ die Darstellung der Fehlermeldung korrumpieren.
Das PDF-Dokument im nächsten Beispiel enthält einen Layer-Namen, der UTF-16BE-Zeichen enthält. Um die Wirkung der Unicode-Zeichen in der Fehlermeldung zu zeigen, wurde der erwartet Layername bewusst falsch gewählt:
<!-- The name of the layers consists of UTF-16BE and contains the byte order mark (BOM). The error message is not complete. It was corrupted by the internal Null-bytes. Adobe Reader® shows: "Ebene 1(4)" The used String is_: "Ebene _XXX" --> <testcase name="hasLayer_NameContainingUnicode_UTF16_ErrorIntended" errorExpected="YES" > <assertThat testDocument="unicode/unicode_layerName.pdf"> <hasLayer> <withName> <matchingComplete> \u00fe\u00ff\u0000E\u0000b\u0000e\u0000n\u0000e\u0000 \u0000_XXX </matchingComplete> </withName> </hasLayer> </assertThat> </testcase>
Wenn die Tests mit ANT ausgeführt wurden, zeigt ein Browser die
von PDFUnit erzeugte Fehlermeldung fehlerfrei an, einschließlich
der Zeichenkette þÿEbene _XXX
am Ende:
Im praktischen Betrieb trat einmal ein Problem auf, bei dem ein „non-breaking space“ in den Testdaten enthalten war, das zunächst als normales Leerzeichen wahrgenommen wurde. Der String-Vergleich lieferte aber einen Fehler, der erst durch die Verwendung von Unicode beseitigt werden konnte:
<!-- The content of the node value terminates with the Unicode value 'non-breaking space'. --> <testcase name="nodeValueWithUnicodeValue"> <assertThat testDocument="xfa/xfaBasicToggle.pdf"> <hasXFAData> <!-- The line is wrapped for printing: --> <withNode tag="default:p[7]" value="The code for creating the toggle behavior involves switching the border between raised and lowered, and maintaining the button's\u00A0" defaultNamespace="http://www.w3.org/1999/xhtml" /> </hasXFAData> </assertThat> </testcase>