2016-11-03 56 views
0

我已經使用CheckCharacters的重寫設置實現了我的XmlTextReader。事情是這樣的:XmlTextReader在規範化處於打開狀態時忽略CheckCharacters = false

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

+0

你能提供一些最小的XML來重現嗎? –

+0

當然可以。你去 - https://gist.github.com/ncksol/29bd6490edd0580c25f7338b417b37d3 –

+0

爲什麼你會從'XmlTextReader'繼承,而不是僅僅傳遞'XmlReaderSettings'到'XmlTextReader.Create'?我不確定這種重寫'Settings'的方式甚至是合法的,因爲它不會*返回讀者創建的設置。 –

回答

1

這似乎是在執行一個缺點:

  • XmlReader沒有Normalization財產。
  • XmlReader.Create允許您通過CheckCharacters作爲設置,但由於它返回XmlReader,因此無法通過它來控制規範化。
  • XmlTextReader(實際包裝XmlTextReaderImpl)有Normalization,但沒有公開CheckCharacters財產,也沒有辦法接受​​。
  • 最後,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); 

哈克,但仍遠遠超過最好實現XmlTextReader從頭其中,由於所有的在實施中的聰明之處,並非輕描淡寫。

注意XmlReader.Create合同有義務返回具有Normalization屬性類型的實例,它只是發生在當前實現這樣做。

相關問題