xml ドキュメントをコンパクトな形式でディスクに書き込みたいと考えています。この目的のために、私はネット フレームワーク メソッドを使用します。XmlDictionaryWriter.CreateBinaryWriter(Stream stream,IXmlDictionary dictionary)
このメソッドは、カスタム コンパクト バイナリ xml 表現を書き込みます。これは後で で読み取ることができますXmlDictionaryWriter.CreateBinaryReader
。このメソッドは、共通の文字列を含むことができる を受け入れるXmlDictionary
ため、それらの文字列を毎回出力に出力する必要はありません。文字列の代わりに、辞書のインデックスがファイルに出力されます。CreateBinaryReader
後で同じ辞書を使用してプロセスを逆にすることができます。
しかし、私が渡す辞書は明らかに使用されていません。次のコードを検討してください。
using System.IO;
using System.Xml;
using System.Xml.Linq;
class Program
{
public static void Main()
{
XmlDictionary dict = new XmlDictionary();
dict.Add("myLongRoot");
dict.Add("myLongAttribute");
dict.Add("myLongValue");
dict.Add("myLongChild");
dict.Add("myLongText");
XDocument xdoc = new XDocument();
xdoc.Add(new XElement("myLongRoot",
new XAttribute("myLongAttribute", "myLongValue"),
new XElement("myLongChild", "myLongText"),
new XElement("myLongChild", "myLongText"),
new XElement("myLongChild", "myLongText")
));
using (Stream stream = File.Create("binaryXml.txt"))
using (var writer = XmlDictionaryWriter.CreateBinaryWriter(stream, dict))
{
xdoc.WriteTo(writer);
}
}
}
生成される出力は次のとおりです (バイナリ制御文字は示されていません)
@
myLongRootmyLongAttribute˜myLongValue@myLongChild™
myLongText@myLongChild™
myLongText@myLongChild™
myLongText
したがって、明らかに XmlDictionary は使用されていません。すべての文字列は、複数回であっても、そのまま出力に表示されます。
これは XDocument に限った問題ではありません。上記の最小限の例では、問題を示すために XDocument を使用しましたが、最初は XmlDictionaryWriter を DataContractSerializer と組み合わせて使用しているときに、一般的に使用されているため、これに遭遇しました。結果は同じでした:
[Serializable]
public class myLongChild
{
public double myLongText = 0;
}
...
using (Stream stream = File.Create("binaryXml.txt"))
using (var writer = XmlDictionaryWriter.CreateBinaryWriter(stream, dict))
{
var dcs = new DataContractSerializer(typeof(myLongChild));
dcs.WriteObject(writer, new myLongChild());
}
結果の出力は、私の XmlDictionary を使用しませんでした。
提供された XmlDictionary を使用するように XmlDictionaryWriter を取得するにはどうすればよいですか?
または、これがどのように機能するかを誤解していますか?
DataContractSerializer アプローチで、ネット フレームワーク コードのデバッグを試みました ( Visual Studio/options/debugging/enable net.framework source stepping )。どうやら Writer は、予想どおり、上記の各文字列を辞書で検索しようとします。ただし、XmlbinaryWriter.cs の 356 行目でルックアップが失敗します。その理由は明らかではありません。
私が検討した代替案:
XmlDictionaryWriter.CreatebinaryWriter のオーバーロードがあり、XmlBinaryWriterSession も受け入れます。次に、ライターは、検出した新しい文字列をセッション ディクショナリに追加します。ただし、事前にわかっている読み書き用の静的辞書のみを使用したい。
全体を にラップして
GzipStream
、圧縮で文字列の複数のインスタンスを処理できるようにすることができます。ただし、これは各文字列の最初のインスタンスを圧縮しないため、全体的に扱いにくい回避策のように思えます。