C# 在使用XmlWriter时,是否有方法控制XML内部文本的编码

C# 在使用XmlWriter时,是否有方法控制XML内部文本的编码,c#,xml,character-encoding,C#,Xml,Character Encoding,我有一个组件,通过XML序列化和XSL转换的组合从对象创建XML文档;生成的文档作为XDocument对象处理。我使用XDocument.Save(TextWriter)方法使用UTF-8编码将文档保存到磁盘,如: XDocument doc = this.CreateDocumentFrom(...); using (Stream stream = File.OpenWrite(...)) { var encoding = new UTF8Encoding(false); va

我有一个组件,通过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);
    }

    ...
}
最后,我覆盖了几乎所有内容,以确定编写器调用了编码类的哪些方法,但在调用
XmlWriter.Create(Stream,XmlWriterSettings)
方法时,只调用了
GetCharCount(…)
重载。我觉得我走错了方向


XmlTextWriter
XmlWriter
创建派生类对我来说也是错误的,因为这样我就不能再使用
XmlWriter.Create(Stream,XmlWriterSettings)
,这是创建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()
方法,该方法将在原始类上执行相同的操作。

非常感谢;这个答案确实很有帮助。我实现了一个在序列化之前清理对象图的方法。。。