2009-01-14 8 views
21

Ich verwende JAXP, um ein XML-Dokument zu generieren und zu analysieren, von dem einige Felder aus einer Datenbank geladen werden.Erstellen von gültigem XML mit Java und UTF-8 Codierung

-Code die XML-Serialisierung:

DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder(); 
Document doc = builder.newDocument(); 
Element root = doc.createElement("test"); 
root.setAttribute("version", text); 
doc.appendChild(root); 

DOMSource domSource = new DOMSource(doc); 
TransformerFactory tFactory = TransformerFactory.newInstance(); 

FileWriter out = new FileWriter("test.xml"); 
Transformer transformer = tFactory.newTransformer(); 
transformer.setOutputProperty(OutputKeys.INDENT, "yes"); 
transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8"); 
transformer.transform(domSource, new StreamResult(out)); 

Code, um das XML zu analysieren:

DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); 
factory.setNamespaceAware(true); 
DocumentBuilder builder = factory.newDocumentBuilder(); 
Document doc = builder.parse("test.xml"); 

Und ich stoßen die folgende Ausnahme:

[Fatal Error] test.xml:1:4: Invalid byte 1 of 1-byte UTF-8 sequence. 
Exception in thread "main" org.xml.sax.SAXParseException: Invalid byte 1 of 1-byte UTF-8 sequence. 
    at org.apache.xerces.parsers.DOMParser.parse(Unknown Source) 
    at org.apache.xerces.jaxp.DocumentBuilderImpl.parse(Unknown Source) 
    at javax.xml.parsers.DocumentBuilder.parse(Unknown Source) 
    at com.test.Test.xml(Test.java:27) 
    at com.test.Test.main(Test.java:55) 

Der Text String enthält u- Umlaut und O-Umlaut (Zeichencodes 0xFC und 0xF6). Dies sind die Zeichen, die den Fehler verursachen. Wenn ich die Schnur selbst entziehe, um & #xFC zu verwenden; und & # xF6; dann geht das Problem weg. Andere Entitäten werden automatisch codiert, wenn ich das XML ausschreibe.

Wie erhalte ich meine Ausgabe ohne Einsetzen dieser Zeichen selbst richtig geschrieben/gelesen werden?

(ich folgende Fragen habe bereits gelesen:

How to encode characters from Oracle to XML?

Repairing wrong encoding in XML files)

Antwort

31

ein Outputstream verwenden, anstatt ein Filewriter.

Letzterer seine eigene Codierung gilt, die mit ziemlicher Sicherheit nicht UTF-8 (je nach Plattform, ist es wahrscheinlich von Windows-1252 oder IS-8859-1).

Edit (jetzt, dass ich einige Zeit haben):

Ein XML-Dokument ohne Prolog erlaubt ist als UTF-8 oder UTF-16 codiert werden. Mit einem Prolog kann er seine Kodierung angeben (der Prolog kann nur US-ASCII-Zeichen enthalten, daher ist Prolog immer lesbar).

Ein Reader befasst sich mit Zeichen; Es wird den Byte-Stream des zugrunde liegenden InputStream dekodieren. Wenn Sie also einen Reader an den Parser übergeben, sagen Sie ihm, dass Sie die Codierung bereits durchgeführt haben, sodass der Parser den Prolog ignoriert. Wenn Sie einen InputStream (der Byte liest) übergeben, wird diese Annahme nicht gemacht, und der Prolog wird zur Definition der Codierung verwendet - oder standardmäßig UTF-8/UTF-16, wenn er nicht vorhanden ist.

Ich habe nie versucht, eine Datei zu lesen, die in UTF-16 codiert wird. Ich vermute, dass der Parser nach einer Byte Order Mark (BOM) als die ersten 2 Bytes der Datei suchen wird.

+0

Schön und einfach, ich habe daran gedacht, dies zu ändern, aber die Idee verworfen, da ich keine Möglichkeit sah, die Codierung im Konstruktor anzugeben. Es hat gut funktioniert, danke. –

+0

Ich habe mich einmal mit FileWriter in den Fuß geschossen .... +1 –

+0

Ausgezeichnete Antwort - Ich werde von nun an immer nach versteckten Gotchas in FileWriter suchen! –

5

Nun, sicher 0xFC und 0xF6 sind nicht gültig UTF-8 Zeichen. Diese sollten auf die zwei Byte-Sequenzen abgestimmt sein: 0x3CBC und 0x3CB6.

Wahrscheinlich ist das Problem mit der ursprünglichen Quelle der Charaktere als UTF-8 definiert werden, wenn sie nicht sind.

+0

Das Ändern des FileWriter zu einem FileOutputStream führte tatsächlich dazu, dass diese Zeichen mit zwei Bytefolgen codiert wurden: 0xC3BC und 0xC3B6. –

Verwandte Themen