启用“规范化”时,XmlTextReader忽略CheckCharacters = false

时间:2016-11-03 14:31:51

标签: c# xml

我已经实现了我的XmlTextReader,其中包含了CheckCharacters的重写设置。像这样:

class MyXmlTextReader : XmlTextReader
{
    public MyXmlTextReader(TextReader input) : base(input)
    {
    }

    /// <summary>
    /// Settings
    /// </summary>
    public override XmlReaderSettings Settings
    {
        get { return new XmlReaderSettings { CheckCharacters = false }; }
    }
}

当我在普通情况下使用无效的xml数据时,一切正常:

var sr3 = new StringReader(xml);
var xr3 = new MyXmlTextReader(sr3);
var obj3 = (MyObject)ser.Deserialize(xr3);

但是一旦我打开规范化,我就开始获得InvalidCharacter异常:

var sr3 = new StringReader(xml);
var xr3 = new MyXmlTextReader(sr3);
xr3.Normalization = true;
var obj3 = (MyObject)ser.Deserialize(xr3);

有没有办法进行规范化,但同时忽略无效的xml字符?

以下是重现问题的示例应用程序: https://gist.github.com/ncksol/29bd6490edd0580c25f7338b417b37d3

1 个答案:

答案 0 :(得分:1)

这似乎是实施中的一个缺点:

  • XmlReader没有Normalization属性。
  • XmlReader.Create允许您将CheckCharacters作为设置传递,但由于它返回XmlReader,您无法通过它控制规范化。
  • XmlTextReader(实际上包裹XmlTextReaderImpl)包含Normalization,但没有公开CheckCharacters属性,也无法接受XmlReaderSettings
  • 最后,执行所有实际工作的XmlTextReaderImpl可以执行规范化和省略字符检查,但由于上述所有原因,没有公共路径来配置它那样。

如果你不介意在这种情况下依赖于实现,可以通过反思来完成:

var sr3 = new StringReader(xml);
var xr3 = XmlReader.Create(sr3, new XmlReaderSettings { CheckCharacters = false });
// xr3.Normalization is not accessible
xr3.GetType()
    .GetProperty("Normalization", BindingFlags.Instance | BindingFlags.NonPublic)
    .SetValue(xr3, true);

var obj3 = (MyObject)ser.Deserialize(xr3);

Hacky,但是仍然比从头开始实现XmlTextReader更可取了,考虑到实现中的所有聪明,这不是轻率的。

请注意,XmlReader.Create 合同有义务返回具有Normalization属性的类型的实例,它恰好在当前实现中执行此操作。< / p>