【问题标题】:Using .NET to validate XML against a schema使用 .NET 针对架构验证 XML
【发布时间】:2010-08-10 13:03:26
【问题描述】:

我想测试(真或假)任意 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()) { }
   }

我的问题是,如果我在未连接到 Internet 的机器上运行此代码,则会收到 XmlSchemaValidationException 错误,大意是找不到 xml.xsd

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

但是当机器连接到互联网时,我现在收到一条错误消息,提示 The global attribute 'http://www.w3.org/XML/1998/namespace:lang' has already been declared.

所以显然我需要明确添加它,或者我不需要,这取决于机器是否能够从互联网上静默下载它(或者甚至可能以前能够下载它,并将它缓存在某个地方)。

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

【问题讨论】:

    标签: .net xml xsd xml-validation


    【解决方案1】:

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

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

    【讨论】:

    • 感谢您的建议;我将尝试使用子类System.Xml.XmlResolver 来修复它。
    • 我现在可以正常工作了。我以前失败过,因为我分配给XmlReaderSettings.XmlResolver 属性;但是当/因为我使用settings.Schemas.Add,因此我需要分配给settings.Schemas.XmlResolver 属性。
    • @ChrisW:我还收到错误“全局属性 'w3.org/XML/1998/namespace:lang' 已被声明。”,代码与您原来的问题类似。您是否将 settings.Schemas.XmlResolver 设置为 XMLCatalogResolver 或其他?我没有运气就试过了。你有机会粘贴你的工作代码吗?
    • 嗨 ChrisW,你在哪里找到了 wordML xsd?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-02-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多