2012-03-26 18 views
2

我正在處理一些在運行時加載xml文件的代碼。在那一刻,我們使用XmlDocument類型來讀取xml文件並圍繞SelectSingleNode語句包裝一個try-catch(這是在一個節點爲空或不存在的情況下完成的,因爲我們解析用戶創建xml文件)。在C#中使用模式進行XML解析#

請注意:我意識到XmlDocument已被替換爲XDocument。但是,由於我們正在使用.NET版本3(according to this MSDN document XDocument在.NET 3中不可用),所以我們現在必須堅持使用XmlDocument。我們使用.NET 3的原因有很多(其中一些與規範相關)。

下面是我們在一分鐘做什麼的例子:

private void LoadUserXMLFile() 
{ 
    XmlDocument xDoc = new XmlDocument(); 
    XmlTextReader reader = new XmlTextReader(fileName); 
    reader.Read(); 
    xDoc.Load(reader); 

    try { firstElementString = xDoc.SelectSingleNode(<path to node>).InnderText); 
    catch { <exception handling here > } 
    //more SelectSingleNode statements, each wrapped inside 
    //individual try-catch blocks 
} 

顯然,上面是一個例子,我已經簡化catch語句。

我已經爲用戶生成的XML文件編寫了一個模式,該應用程序可以使用,並且我想知道如果我在解析XML文檔時使用了模式(以某種方式),是否仍然需要打包每個SelectSingleNode都帶有try-catch語句?

甚至可以在解析過程中使用模式(以某種方式)檢查XML文檔是否具有正確的格式和所有必需的元素?

回答

2

是的,你需要使用一個驗證讀取器

您可以使用類似這樣

XmlTextReader r = new XmlTextReader("C:\\Xml\\MyXmlFile.xml"); 
v.ValidationType = ValidationType.Schema; 

顯然你的XML將參考架構,以便多數民衆贊成在參考該如何解決(在XML本身),像這樣

<Employee EmployeeId="12345566" 
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
     xsi:noNamespaceSchemaLocation="Employee.xsd"> 
    <PersonName>Krystan</PersonName> 
</Employee> 

,如果你不能改變的XML,您可以使用XmlReaderSettings這樣

public void SomeMethod() 
{ 
    XmlReaderSettings xmlsettings = new XmlReaderSettings(); 
    xmlsettings.Schemas.Add("http://www.company.com/blah", "blah.xsd"); 
    xmlsettings.ValidationType = ValidationType.Schema; 
    xmlsettings.ValidationEventHandler += new ValidationEventHandler(ValidationHandler); 

    XmlReader reader= XmlReader.Create("somefile.xml", xmlsettings); 

    while (reader.Read()) { } 
} 

public void ValidationHandler(object sender, ValidationEventArgs args) 
    void booksSettingsValidationEventHandler(object sender, ValidationEventArgs e) 
{ 
    if (e.Severity == XmlSeverityType.Warning) 
    { 
     Console.Write("WARNING: "); 
     Console.WriteLine(e.Message); 
    } 
    else if (e.Severity == XmlSeverityType.Error) 
    { 
     Console.Write("ERROR: "); 
     Console.WriteLine(e.Message); 
    } 
} 

要回答你的問題,如果你已經針對一個模式進行了驗證,並且選擇已知在那裏的節點,你可以免除每個節點異常的困擾,但顯然你應該防範由於文件加載等原因可能發生的異常。