F: Validator meldet „UTF-8 mit BOM“ – ist meine E-Rechnung ungültig?

Thema
VB.NET
SDK-Mitglieder
ReadAllBytes()
Codebeispiele
VB.NET, VB6 / VBScript (COM)
Veröffentlicht

Kurz: Nein, die Rechnung bleibt gültig. Der Hinweis „Die Datei liegt im Zeichensatz UTF-8 BOM vor“ (bei valitool zum Beispiel [VD-Valitool-130]) bedeutet nur, dass das XML mit drei unsichtbaren Bytes beginnt, dem Byte Order Mark (BOM, hexadezimal EF BB BF). Das betrifft XRechnung, ZUGFeRD und Factur-X gleichermaßen. Manche Empfangssysteme kommen damit nicht zurecht, deshalb ist UTF-8 ohne BOM die sichere Wahl. Das Aloaha ZUGFeRD SDK speichert das XML mit SaveXML standardmäßig ohne BOM. Meldet der Validator trotzdem einen BOM, wurde die XML-Datei meist von der eigenen Anwendung geschrieben oder nachträglich geändert.

So prüfen Sie, ob die Datei einen BOM hat

Öffnen Sie die XML-Datei in einem Hex-Editor oder lesen Sie die ersten drei Bytes. Sind es EF BB BF, hat die Datei einen BOM. Ohne BOM beginnt sie direkt mit <?xml (3C 3F 78 6D 6C).

' VB.NET
Dim b() As Byte = System.IO.File.ReadAllBytes(xmlPfad)
Dim hatBom As Boolean = b.Length >= 3 AndAlso b(0) = &HEF AndAlso b(1) = &HBB AndAlso b(2) = &HBF

Woher der BOM kommt

UrsacheLösung
Im Code steht alo.SaveWithoutBOM = False.Die Zeile entfernen oder True setzen. True ist der Standard.
Die Anwendung ändert die XML-Datei nach SaveXML und schreibt sie neu, in .NET z. B. mit File.WriteAllText(pfad, text, Encoding.UTF8) oder einem StreamWriter mit Encoding.UTF8.Mit New UTF8Encoding(False) schreiben, siehe unten.
VBA schreibt das XML mit ADODB.Stream und Charset = "utf-8". Diese Methode setzt immer einen BOM.Die ersten drei Bytes vor dem Speichern abschneiden, siehe unten. Oder das XML direkt mit SaveXML speichern lassen.
Das XML wurde in einem Editor geöffnet und als „UTF-8 mit BOM“ gespeichert.Als „UTF-8“ (ohne BOM) speichern oder die Datei neu erzeugen.

MergeXMLIntoPDF bettet die XML-Datei ein, die Sie übergeben. Ein BOM in dieser Datei steht deshalb auch im XML der ZUGFeRD-PDF.

XML in .NET ohne BOM speichern

' VB.NET
System.IO.File.WriteAllText(xmlPfad, xmlText, New System.Text.UTF8Encoding(False))

Encoding.UTF8 schreibt einen BOM, New UTF8Encoding(False) nicht. Das gilt auch für StreamWriter und XmlWriterSettings.Encoding.

XML in VBA ohne BOM speichern

' VBA: UTF-8 ohne BOM mit zwei ADODB.Stream-Objekten
Dim s As Object, b As Object
Set s = CreateObject("ADODB.Stream")
s.Type = 2: s.Charset = "utf-8": s.Open
s.WriteText xmlText
s.Position = 3                      ' die drei BOM-Bytes überspringen
Set b = CreateObject("ADODB.Stream")
b.Type = 1: b.Open
s.CopyTo b
b.SaveToFile xmlPfad, 2             ' 2 = überschreiben
b.Close: s.Close

Häufige Fragen

Ist eine E-Rechnung mit UTF-8 BOM ungültig?

Nein. Prüfportale geben nur einen Hinweis aus, weil manche Empfangssysteme mit dem BOM Probleme haben. UTF-8 ohne BOM ist die sichere Wahl.

Speichert das Aloaha ZUGFeRD SDK das XML mit BOM?

Nein. SaveXML speichert standardmäßig als UTF-8 ohne BOM. Die Eigenschaft SaveWithoutBOM ist dafür standardmäßig True.

Woher kommt der BOM in meiner ZUGFeRD-PDF?

Aus der XML-Datei, die an MergeXMLIntoPDF übergeben wurde. Meist hat die eigene Anwendung sie mit Encoding.UTF8 oder ADODB.Stream neu geschrieben.

Woran erkenne ich einen BOM?

Die Datei beginnt mit den drei Bytes EF BB BF statt direkt mit <?xml. Ein Hex-Editor oder die ersten drei Bytes aus ReadAllBytes zeigen es.

Wie speichere ich in .NET ohne BOM?

Mit New UTF8Encoding(False) statt Encoding.UTF8, zum Beispiel in File.WriteAllText oder im StreamWriter.