2015-07-07

[筆記]如何以自訂XML的方式對其他XML做驗證

最近的專案內有個需求,對方會傳來一組XML,而我們必須針對不同的狀況來對這組XML做驗證,判斷Tag是否都符合所需;而不同的狀況所需要的Tag是不相同的,所以必須在資料庫內紀錄每個狀況所需要的XML Tag。

其實重點就是,我們如何用特定的XML(以A來簡稱),去驗證其他XML(以B來簡稱),看看B是否符合A的規則?



其實直接設定XSD是比較好的,因為可以直接拿來驗證XML是否符合XSD的規則,但XSD又臭又長又難寫,要開一組新規則還要研究XSD怎麼寫實在太麻煩了,所以規則採用XML來記錄,然後把規則XML轉乘XSD就好。

例如我們有一組規則,必須符合底下的XML才算通過:
<Root><nodeA></nodeA><nodeB></nodeB></Root>

我們就只要設定上面的XML規則,然後利用底下的程式碼將規則轉成XSD,就可以對對方傳來的XML做驗證了:

using System.Xml.Linq;
using System.Xml.Schema;
using System.Xml;
using System.IO;

public bool ValidateXml(string template, string xml) {
    XDocument t = XDocument.Parse(template); //樣板Xml的XDocument物件
    XDocument x = XDocument.Parse(xml); //對方傳來Xml的XDocument物件
    
    //底下可產生樣板XML的XSD
    XmlReader reader = XmlReader.Create(new StringReader(t.Root.ToString()));
    XmlSchemaSet schemaSet = new XmlSchemaSet();
    XmlSchemaInference schema = new XmlSchemaInference();
    schemaSet = schema.InferSchema(reader);

    bool result = true;
    //使用XDocument裡的Validate擴充方法,將XSD傳入做驗證
    x.Validate(schemaSet, (sender, e) => {
        result = false; //如果驗證失敗才會進來的區塊,可自訂處理動作,這裡僅將結果設為false
    });
    return result;
}

如此只要把樣板XML與傳來的XML丟到這個function就可以囉~