我有一个组件,它通过XML序列化和XSL转换的组合从对象创建XML文档;所得到的文档被作为CCD_ 1对象来处理。我使用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类的哪些方法,但在调用XmlWriter.Create(Stream, XmlWriterSettings)
方法时,只调用GetCharCount(...)
的重载。我感觉自己走错了路。。。
从XmlTextWriter
或XmlWriter
创建派生类对我来说也是错误的,因为这样我就不能再使用XDocument
0了,这是创建XmlWriter实例的推荐方法。
如果是我,我会在调用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
序列化为SomeFoo
。
或者,为了在没有新类的情况下获得类似的效果,请创建一个ScrubForSerialization()
方法,该方法将对原始类执行相同的操作。