我有一个组件,它通过XML序列化和XSL转换的组合从对象创建XML文档;生成的文档作为XDocument
对象处理。我使用XDocument.Save(TextWriter)
方法使用UTF-8编码将文档保存到磁盘,例如:
XDocument doc = this.CreateDocumentFrom(...);
using (Stream stream = File.OpenWrite(...))
{
var encoding = new UTF8Encoding(false);
var settings = new XmlWriterSettings { Encoding = encoding };
using (var writer = XmlWriter.Create(stream, settings))
{
doc.Save(writer);
}
}
创建文档并将其写入磁盘可以正常工作。现在,我要求XML中的文本值必须有一个特殊的编码(只允许ASCII字符的一小部分,让我们说大小写字母除了变异的元音,数字和一些特殊的字符,如逗号,点,...)。所以,我认为我可以简单地继承UTF8Encoding
类,并通过仅过滤无效字符来覆盖一些方法来实现所需行为。我试图覆盖GetBytes(string)
和GetString(byte[])
,但它没有用。似乎XmlWriter根本不使用给定的编码实例。
这就是我试过的......
public sealed class CustomEncoding : UTF8Encoding
{
private const string ValidChars = "abc...xyzABC...XYZ0...9";
public CustomEncoding() : base(false) { }
public override byte[] GetBytes(string s)
{
char[] characters = s.Where(x => ValidChars.Contains(x)).ToArray();
return base.GetBytes(characters);
}
...
}
最后,我几乎覆盖了所有内容,以确定编写器调用Encoding类的哪些方法,但调用GetCharCount(...)
方法时只调用XmlWriter.Create(Stream, XmlWriterSettings)
的重载。我觉得我走错了路......
从XmlTextWriter
或XmlWriter
创建派生类对我来说也感觉不对,因为我不能再使用XmlWriter.Create(Stream, XmlWriterSettings)
,这是创建XmlWriter实例的推荐方法。
答案 0 :(得分:2)
如果是我,我会在调用XmlWriter
之前清理数据(可能是类的实例?)。我甚至可以从你要序列化的类中创建一个派生类,然后序列化那个。
举个例子:
public class SomeFoo
{
public string SomeTextValue {get; set;}
}
public class SomeDerivedFoo : SomeFoo
{
private SomeDerivedFoo();
public static SomeDerivedFoo CreateFromSomeFoo(SomeFoo someFoo)
{
base.SomeTextValue = //scrub your data here;
}
}
然后,在您的XmlWriter中,序列化SomeDerivedFoo
AS SomeFoo
。
或者,对于没有新类的类似效果,创建一个ScrubForSerialization()
方法,它将在原始类上执行相同的操作。