アプリケーションに次の XML 解析コードがあります。
public static XElement Parse(string xml, string xsdFilename)
{
var readerSettings = new XmlReaderSettings
{
ValidationType = ValidationType.Schema,
Schemas = new XmlSchemaSet()
};
readerSettings.Schemas.Add(null, xsdFilename);
readerSettings.ValidationFlags |= XmlSchemaValidationFlags.ProcessInlineSchema;
readerSettings.ValidationFlags |= XmlSchemaValidationFlags.ProcessSchemaLocation;
readerSettings.ValidationFlags |= XmlSchemaValidationFlags.ReportValidationWarnings;
readerSettings.ValidationEventHandler +=
(o, e) => { throw new Exception("The provided XML does not validate against the request's schema."); };
var readerContext = new XmlParserContext(null, null, null, XmlSpace.Default, Encoding.UTF8);
return XElement.Load(XmlReader.Create(new StringReader(xml), readerSettings, readerContext));
}
カスタム逆シリアル化のために、WCF サービスに送信された文字列を XML ドキュメントに解析するために使用しています。
ファイルを読み込んでネットワーク経由で送信すると(リクエスト)、正常に動作します。BOM が送信されていないことを確認しました。私のリクエスト ハンドラでは、レスポンス オブジェクトをシリアル化し、文字列として送り返しています。シリアライゼーション プロセスでは、文字列の前に UTF-8 BOM が追加されるため、応答を解析するときに同じコードが壊れます。
System.Xml.XmlException : Data at the root level is invalid. Line 1, position 1.
この 1 時間ほどで行った調査では、XmlReader は BOM を尊重する必要があるようです。文字列の先頭から BOM を手動で削除すると、応答 xml は正常に解析されます。
明らかな何か、または少なくとも陰湿な何かが欠けていますか?
編集:応答を返すために使用しているシリアル化コードは次のとおりです。
private static string SerializeResponse(Response response)
{
var output = new MemoryStream();
var writer = XmlWriter.Create(output);
new XmlSerializer(typeof(Response)).Serialize(writer, response);
var bytes = output.ToArray();
var responseXml = Encoding.UTF8.GetString(bytes);
return responseXml;
}
BOM が正しく含まれていない xml の問題である場合は、次のように切り替えます。
var responseXml = new UTF8Encoding(false).GetString(bytes);
しかし、私の調査では、BOM が実際の XML 文字列で違法であることはまったく明らかではありませんでした。たとえば、c# Byte Array から xml エンコーディングを検出しますか? を参照してください。