有没有办法在使用XmlWriter时控制XML内部文本的编码

时间:2013-11-19 22:11:30

标签: 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);
    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)的重载。我觉得我走错了路......

XmlTextWriterXmlWriter创建派生类对我来说也感觉不对,因为我不能再使用XmlWriter.Create(Stream, XmlWriterSettings),这是创建XmlWriter实例的推荐方法。

1 个答案:

答案 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()方法,它将在原始类上执行相同的操作。