2010-08-10 110 views
10

我想测试(true或false)任意XML文件是否与给定模式匹配。使用.NET根据模式验证XML

为了什么值得,架构是Word 2003 WordML架构,Microsoft使用大约7 *.xsd文件列表定义。

这些文件之一还包括W3C xml.xsd文件,通过包括以下语句:

<xsd:import id="xml" namespace="http://www.w3.org/XML/1998/namespace" 
    schemaLocation="http://www.w3.org/2001/xml.xsd"></xsd:import> 

我使用像.NET代码下面做验证:

public static void validate(string filename) 
    { 
     XmlReaderSettings settings = new XmlReaderSettings(); 
     settings.Schemas.Add(
      "http://schemas.microsoft.com/office/word/2003/wordml", 
      //to get this file I downloaded "Office 2003: XML Reference Schemas", i.e. "Office2003XMLSchema.exe" 
      @"C:\Program Files\Microsoft Office 2003 Developer Resources\Microsoft Office 2003 XML Reference Schemas\WordprocessingML Schemas\wordnet.xsd" 
      ); 
     settings.ValidationType = ValidationType.Schema; 
     settings.ValidationEventHandler += new ValidationEventHandler(validationEventHandler); 
     XmlReader xmlReader = XmlReader.Create(filename, settings); 
     while (xmlReader.Read()) { } 
    } 

我问题是,如果我在没有连接到互联网的机器上运行此代码,那么我得到一个XmlSchemaValidationException错误,以至于无法找到xml.xsd

要解决此问题,我下载了xml.xsd的一个副本,并使用settings.Schemas.Add方法明确添加它:当机器未连接到互联网时,验证现在可以正常工作。

但是,当机器连接到互联网,我现在得到一个错误,说The global attribute 'http://www.w3.org/XML/1998/namespace:lang' has already been declared.

因此,显然我需要明确地添加它,或者我不这样做,具体取决于机器是否能够静默地从互联网上下载它(或者甚至可能以前已经能够下载它并且已经缓存某处)。

所以,如果我这样做是“该死的,如果我不这样做就该死”。我是否需要尝试一种方法,捕捉异常,然后以另一种方式尝试它?还是有更优雅的解决方案?

回答

4

我们看不到您的代码,但是 在许多实现中,这是通过使用目录解析器将.xsd的请求重定向到本地副本来处理的。有一个属性XmlReaderSettings.XmlResolver可用于此。请参阅XMLCatalog.net以获取您可以使用的Apache许可实施。

这样做的副作用是您可以保留本地缓存所有模式。这一点尤其重要,因为W3C会阻止对他们网站的过度读取,并随机地将您的代码(或者更糟的是,您的客户代码)开始失败。

+0

谢谢你的建议;我将试验看看我是否可以通过使用子类“System.Xml.XmlResolver”来修复它。 – ChrisW 2010-08-19 13:46:26

+1

我现在正在工作。之前我失败了,因为我正在分配给'XmlReaderSettings.XmlResolver'属性;但是当/因为我正在使用'settings.Schemas.Add'时,我需要分配给'settings.Schemas.XmlResolver'属性。 – ChrisW 2010-08-19 18:55:30

+1

@ChrisW:我也收到错误“全局属性'http://www.w3.org/XML/1998/namespace:lang'已被声明。”,与您原来的问题中的代码类似。您是否已将settings.Schemas.XmlResolver设置为XMLCatalogResolver或其他?我试过,没有运气。任何机会,你可以粘贴你的工作代码? – Jeremy 2011-11-10 18:19:11