眾所周知XML是可以擴充的,XML的元素可以靠名稱識別而不是只按照未知識別。在XML還原序列化的時候只要需要的資訊存在就可以成功將XML資料轉化成還原序列化後的對象。但是這並不代表著用來還原序列化的XML資料就一定是序列化的標準結果。有些時候XML資料會有多餘冗長資訊,這個在還原序列化的過程中預設是不會被覺察到的。
XmlSerializer類型有三個事件可以覺察到未知XML節點:UnknownNode,UnknownElement和UnknownAttribute。分別對應未知節點,未知元素和未知屬性。注意XML元素和XML屬性都屬於XML節點。
比如這個類型:
public class Worker
{
public int Id;
[XmlAttribute]
public bool Retired;
}
本只包括一個元素(Id)和屬性(Retired),但XML資料中還有其他冗長資訊:
<?xml version="1.0" encoding="utf-8" ?>
<Worker xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
Retired="false"
Department="sales">
<Name>Mgen</Name>
<Id>17</Id>
</Worker>
註冊XmlSerializer的相應事件然後還原序列化操作:
var xmlSerializer = new XmlSerializer(typeof(Worker));
xmlSerializer.UnknownNode += (sender, e) =>
{
Console.WriteLine("未知節點:{0} 行{1} 列{2}", e.Name, e.LineNumber, e.LinePosition);
};
xmlSerializer.UnknownAttribute += (sender, e) =>
{
Console.WriteLine("位置屬性:{0} 行{1} 列{2}", e.Attr.Name, e.LineNumber, e.LinePosition);
};
xmlSerializer.UnknownElement += (sender, e) =>
{
Console.WriteLine("位置元素:{0} 行{1} 列{2}", e.Element.Name, e.LineNumber, e.LinePosition);
};
//還原序列化XML檔案
var worker = (Worker)xmlSerializer.Deserialize(File.OpenRead("xmlfile.xml"));
輸出:
未知節點:Department 行5 列21
位置屬性:Department 行5 列21
未知節點:Name 行7 列6
位置元素:Name 行7 列6