web-dev-qa-db-ja.com

XDocument:BOMなしでファイルにXMLを保存する

XDocumentを使用してutf-8 XMLファイルを生成しています。

XDocument xml_document = new XDocument(
                    new XDeclaration("1.0", "utf-8", null),
                    new XElement(ROOT_NAME,                    
                    new XAttribute("note", note)
                )
            );
...
xml_document.Save(@file_path);

ファイルは正しく生成され、xsdファイルで検証され、成功します。

XMLファイルをオンラインサービスにアップロードしようとすると、ファイルにwrong at line 1;問題の原因がファイルの最初のバイトのBOMであることを発見しました。

BOMがファイルに追加される理由と、それなしでファイルを保存する方法を知っていますか?

バイトオーダーマーク ウィキペディアの記事で述べたように:

Unicode標準ではUTF-8でのBOMが許可されていますが、BOMは必要ありませんし、推奨もされていません。 UTF-8ではバイト順は意味がないため、BOMはテキストストリームまたはファイルをUTF-8として、またはBOMを持つ別の形式から変換されたことを識別するためにのみ機能します。

XDocumentの問題ですか、それともオンラインサービスプロバイダーに連絡して、パーサーのアップグレードを依頼する必要がありますか?

41
systempuntoout

XmlTextWriterを使用してXDocumentのSave()メソッドに渡します。これにより、使用するエンコーディングのタイプをより詳細に制御できます。

var doc = new XDocument(
    new XDeclaration("1.0", "utf-8", null),
    new XElement("root", new XAttribute("note", "boogers"))
);
using (var writer = new XmlTextWriter(".\\boogers.xml", new UTF8Encoding(false)))
{
    doc.Save(writer);
}

UTF8Encodingクラスコンストラクターには、ブール値でBOM(バイトオーダーマーク)を使用するかどうかを指定するオーバーロードがあり、ケースではfalseです。

このコードの結果は、Notepad ++を使用してファイルのエンコーディングを検査することで検証されました。

69
Quick Joe Smith

まず第一に、サービスプロバイダーは、UTF-8表現の場合にBOMが存在する可能性があると述べているXML仕様に従って、それを処理する必要があります。

次のように、BOMなしでXMLを強制的に保存できます。

XmlWriterSettings settings = new XmlWriterSettings();
settings.Encoding = new UTF8Encoding(false); // The false means, do not emit the BOM.
using (XmlWriter w = XmlWriter.Create("my.xml", settings))
{
    doc.Save(w);
}

(ここからGoogled: http://social.msdn.Microsoft.com/Forums/en/xmlandnetfx/thread/ccc08c65-01d7-43c6-adf3-1fc70fdb026a

30
Dercsár

XDocumentを使用してBOM文字を削除する最も適切な方法は、ドキュメントを保存してから、ファイルをそのままファイルとして読み取り、それを書き戻すことです。 Fileルーチンは文字を取り除きます:

        XDocument xTasks = new XDocument();
        XElement xRoot = new XElement("tasklist",
            new XAttribute("timestamp",lastUpdated),
            new XElement("lasttask",lastTask)
        );
        ...
        xTasks.Add(xRoot);
        xTasks.Save("tasks.xml");

        // read it straight in, write it straight back out. Done.
        string[] lines = File.ReadAllLines("tasks.xml");
        File.WriteAllLines("tasks.xml",lines);

(それはおかしいですが、便宜上機能します-少なくとも、あなたのオンラインプロバイダーにアップロードするための整形式のファイルがあります);)

0
Justin Rivers