Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

XML mit BOM?

46 views
Skip to first unread message

Stefan Matthias Aust

unread,
May 13, 2004, 6:57:46 AM5/13/04
to
Hat sich schon mal jemand mit XML-Dateien mit BOMs herumgeärgert?

Ist das folgende Vorgehen korrekt?

Der XML-Parser benutzt eine sax InputSource. Wie ich die Doku verstehe
prüft er, ob ein Reader vorhanden ist und nutzt den. Andernfalls nimmt
er den binary stream falls vorhanden und sonst ein URI. Okay.

Windows schreibt UTF-8 und UTF-16-Dateien mit BOM. Sowas auch okay.

Benutze ich

factory.newDocumentBuilder().parse(new File(fileName));

macht Java aus dem Dateinamen ein URI und liest die Datei. Ist da ein
BOM drin, wirft der Parser einen Fehler. Mist!

Also benutze ich lieber

factory.newDocumentBuilder().parse(makeInputSource(fileName));

und implementiere:

InputSource makeInputSource(String fileName) {
BufferedInputStream in = new BIS(new FIS(fileName));
in.mark(3);
int c1 = in.read();
int c2 = in.read();
if (c1 == 0xFE && c2 == 0xFF) {
return new InputSource(new InputStreamReader(in, "utf-16be"));
}
// dito utf-16le
// dito utf-8
in.reset();
return new InputSource(in);
}

Wenn also ein BOM vorhanden ist, baue ich den passenden Reader, der dann
ja direkt hinter dem BOM aufsetzt und so das störende Zeichen nicht mehr
enthält.

Finde ich keinen BOM, lass ich den Parser das Format ausbaldovern.
Hoffentlich beachtet er dann das encoding aus der xml processing
instruction.

Habe ich noch was vergessen?


bye
--
Stefan Matthias Aust // "Zweifel sind der Ansporn des Denkens..." -U

Mike Lischke

unread,
May 13, 2004, 12:11:17 PM5/13/04
to
Stefan Matthias Aust wrote

>Hat sich schon mal jemand mit XML-Dateien mit BOMs herumgeärgert?

Ich benutze solche Dateien gerade den lieben langen Tag. Allerdings verwende ich JDOM und dessen SAXBuilder, da brauche ich mir um das Transformationsformat keine Gedanken zu machen.

>Benutze ich
>factory.newDocumentBuilder().parse(new File(fileName));
>macht Java aus dem Dateinamen ein URI und liest die Datei. Ist da ein BOM drin, wirft der Parser einen Fehler. Mist!
>Also benutze ich lieber

Warum machst du nicht sowas:

BufferedReader rawInput = new BufferedReader(new InputStreamReader(input, charset));

? Dann hast du Unicode und kannst das direkt an deinen Parser verfüttern.

Mike
--
www.soft-gems.net

Stefan Matthias Aust

unread,
May 13, 2004, 1:45:25 PM5/13/04
to
Mike Lischke wrote:

>>Hat sich schon mal jemand mit XML-Dateien mit BOMs herumgeärgert?
>
> Ich benutze solche Dateien gerade den lieben langen Tag. Allerdings verwende ich
> JDOM und dessen SAXBuilder, da brauche ich mir um das
> Transformationsformat keine Gedanken zu machen.

Hm, vielleicht misverstehen wir uns oder ich verstehe dich nicht, aber
was soll JDOM besser machen? Wenn ich

System.out.println(new SAXBuilder().build(new File("C:/a.txt")));

auf eine im UTF-8-Format abgespeicherte Datei

$ od -tx1 a.txt
0000000 ef bb bf 3c 3f 78 6d 6c 20 76 65 72 73 69 6f 6e
0000020 3d 22 31 2e 30 22 20 65 6e 63 6f 64 69 6e 67 3d
0000040 22 61 73 63 69 69 22 3f 3e 0d 0a 0d 0a 3c 72 6f
0000060 6f 74 3e 0d 0a 20 3c 65 6c 65 6d 65 6e 74 2f 3e
0000100 0d 0a 3c 2f 72 6f 6f 74 3e 0d 0a
0000113

loslasse, dann liefert mir auch JDOM den Fehler

org.jdom.input.JDOMParseException: Error on line 1 of document
file:/C:/a.txt: Dokumentwurzelelement fehlt
at org.jdom.input.SAXBuilder.build(SAXBuilder.java:462)
at org.jdom.input.SAXBuilder.build(SAXBuilder.java:809)
at org.jdom.input.SAXBuilder.build(SAXBuilder.java:788)
at com.coremedia.applications.drm.opt.Test.main(Test.java:12)
Caused by: org.xml.sax.SAXParseException: Dokumentwurzelelement fehlt
at org.apache.crimson.parser.Parser2.fatal(Parser2.java:3376)

der, wie man sieht, aus dem selben Parser kommt, mit dem ich mich auch
ohne JDOM herumärgere.

> Warum machst du nicht sowas:
>
> BufferedReader rawInput = new BufferedReader(new InputStreamReader(input, charset));

Weil ich das "charset" eben nicht kenne? Das ergibt sich doch erst aus
dem BOM... Der Code, den ich gepostet hatte, berechnet doch gerade das
richtige Encoding...

Ich bin verwirrt.

Bernd Eckenfels

unread,
May 13, 2004, 4:01:12 PM5/13/04
to
Stefan Matthias Aust <s...@3plus4.de> wrote:
> auf eine im UTF-8-Format abgespeicherte Datei

Dann musst du die halt mit einem UTF-8 Reader lesen.

> Weil ich das "charset" eben nicht kenne? Das ergibt sich doch erst aus
> dem BOM... Der Code, den ich gepostet hatte, berechnet doch gerade das
> richtige Encoding...

und in dem fall musst du halt die ersten 10 bytes lesen, charset berechnen
(nach <? suchen) und dann resetten und den richtigen reader draufsetzen.

Gruss
Bernd
--
eckes privat - http://www.eckes.org/
Project Freefire - http://www.freefire.org/

Bodo Wippermann

unread,
May 13, 2004, 5:01:29 PM5/13/04
to
Stefan Matthias Aust wrote:

> Hat sich schon mal jemand mit XML-Dateien mit BOMs herumgeärgert?
>

Nee.


> Ist das folgende Vorgehen korrekt?
>

Ja.


> Der XML-Parser benutzt eine sax InputSource. Wie ich die Doku verstehe
> prüft er, ob ein Reader vorhanden ist und nutzt den. Andernfalls nimmt
> er den binary stream falls vorhanden und sonst ein URI. Okay.
>
> Windows schreibt UTF-8 und UTF-16-Dateien mit BOM. Sowas auch okay.
>

Sollte dir egal sein ( doch nicht siehe unten).


> Benutze ich
>
> factory.newDocumentBuilder().parse(new File(fileName));
>
> macht Java aus dem Dateinamen ein URI und liest die Datei. Ist da ein
> BOM drin, wirft der Parser einen Fehler. Mist!
>

Habe es gerade ausprobiert.
Wenn man den Crimson-Parser aus dem JDK 1.4.x nutzt, dann bekommt man
den Fehler, oops.
--> Nutz Xerces und du dast das Problem nicht mehr (hoffentlich ;)


> Habe ich noch was vergessen?
>

Nee
Gruss
Bodo

Mike Lischke

unread,
May 14, 2004, 1:59:49 PM5/14/04
to
Stefan Matthias Aust wrote

>at org.apache.crimson.parser.Parser2.fatal(Parser2.java:3376)

Das ist der Grund. Ich habe mir Xerces 2.6.2 geholt und der arbeitet ohne Murren. Soweit ich weiß, kann Crimson doch keine Validierung. Deshalb musste ich ohnehin umsteigen (brauche die Validierung). Die IBM Xerces Version 4.x in Eclipse ist aus Xerces 2.0 hervorgegangen und in der Zwischenzeit hat es schon einige Bugfixes gegeben.

>> BufferedReader rawInput = new BufferedReader(new InputStreamReader(input, charset));
>Weil ich das "charset" eben nicht kenne? Das ergibt sich doch erst aus dem BOM...

Also ich habe es nicht selbst probiert, aber wenn du einfach erst einmal annimmst, dass die XML Datei in utf-8 kodiert ist, dann dürfte es auch schnurz sein, ob ein BOM drin steht oder nicht. Der Reader sollte das eigentlich managen. Und falls kein uft-8 drin steht funktioniert es auch noch für den ANSI charset, da die ersten 256 Byte direkt im utf-8 enthalten sind. Ansonsten hast du ohnehin ein Problem besonderer Art. Zunächst werden nicht alle möglichen charsets von allen Java VMs unterstützt und zum anderen gibt es da eine Menge, also ohne Rückfrage und manueller Verbiegung wirst du das nicht gebacken kriegen.

Ist die Annahme, dass eigentlich fast alle XML Dokumente in utf-8 kodiert sind so falsch? Ich habe bisher angenommen, dass das so wäre.

Mike
--
www.soft-gems.net

Mike Lischke

unread,
May 14, 2004, 2:01:36 PM5/14/04
to
Bernd Eckenfels wrote

>und in dem fall musst du halt die ersten 10 bytes lesen, charset berechnen
>(nach <? suchen) und dann resetten und den richtigen reader draufsetzen.

Das ist an sich eine gute Vorgehensweise. Immerhin steht das Encoding ja in der Datei. Und wenn nicht, dann soll laut Spec. ohnehin utf-8 angenommen werden. Da der Header immer nur ASCII Zeichen verwendet sollte es kein Problem geben, das Encoding zu lesen.

Mike
--
www.soft-gems.net

Alexander Reifinger

unread,
May 17, 2004, 2:56:07 AM5/17/04
to
Mike Lischke wrote:

> Ist die Annahme, dass eigentlich fast alle XML Dokumente in utf-8 kodiert sind so falsch?

Ja. Zumindest von Menschen geschriebene XML-Dateien dürften oft mit
Windows-1252 kodiert sein oder was Notepad da so auswirft.

> Ich habe bisher angenommen, dass das so wäre.

Das würde ich nicht tun, dass das nicht funktioniert sieht man immer
wieder an Webseiten, Mails, Posting, ..., die Ümläüte so schön als ?
oder Zeichenmüll darstellen.

--
Servus,
Alexander Reifinger

Bernd Eckenfels

unread,
May 24, 2004, 1:00:19 PM5/24/04
to
Mike Lischke <inv...@soft-gems.net> wrote:
> Das ist an sich eine gute Vorgehensweise. Immerhin steht das Encoding ja
> in der Datei. Und wenn nicht, dann soll laut Spec. ohnehin utf-8
> angenommen werden. Da der Header immer nur ASCII Zeichen verwendet sollte
> es kein Problem geben, das Encoding zu lesen.

Du hast die XML Spec nicht richtig zusammengefasst, aber ja laut spec ist es
immer moeglich das xml encoding zu ermitteln (man muss nach suchmustern
suchen die ebcdic, BOMs oder latinX entsprechen und denn rest aus dem
encoding= parsen, das ist ganz genau beschrieben)

Problem ist nur, es gibt so viele "fast richtigen" xml files (die mit
leerzecihen anfangen, mit zeilenumbruechen, mit kommentaren, etc). Nicht
immer kann man sich leisten, den Erzeuger zu flamen.

0 new messages