2012-03-26 58 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); 
    } 
} 

要回答你的问题,如果你已经针对一个模式进行了验证,并且选择已知在那里的节点,你可以免除每个节点异常的困扰,但显然你应该防范由于文件加载等原因可能发生的异常。