问题描述
我想测试(真或假)任意 XML 文件是否与给定架构匹配.
I want to test (true or false) whether an arbitrary XML file matches a given schema.
值得一提的是,该架构是 Word 2003 WordML 架构,Microsoft 使用大约 7 个 *.xsd
文件的列表来定义它.
For what it's worth, the schema is the Word 2003 WordML schema, which Microsoft defines using a list of about 7 *.xsd
files.
其中一个文件还包括 W3C xml.xsd
文件,包括以下语句:
One of these files also includes the W3C xml.xsd
file, by including the following statement:
<xsd:import id="xml" namespace="http://www.w3.org/XML/1998/namespace"
schemaLocation="http://www.w3.org/2001/xml.xsd"></xsd:import>
我正在使用如下所示的 .NET 代码进行验证:
I am using .NET code like the following to do the validation:
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 FilesMicrosoft Office 2003 Developer ResourcesMicrosoft Office 2003 XML Reference SchemasWordprocessingML Schemaswordnet.xsd"
);
settings.ValidationType = ValidationType.Schema;
settings.ValidationEventHandler += new ValidationEventHandler(validationEventHandler);
XmlReader xmlReader = XmlReader.Create(filename, settings);
while (xmlReader.Read()) { }
}
我的问题是,如果我在未连接到 Internet 的机器上运行此代码,则会收到 XmlSchemaValidationException
错误,大意是找不到 xml.xsd
.
My problem is that if I run this code on a machine which is not connected to the internet, then I get a XmlSchemaValidationException
error to the effect that it can't find xml.xsd
.
为了解决这个问题,我下载了 xml.xsd 的副本,并使用 settings.Schemas.Add
方法显式添加:当机器未连接到 Internet 时,验证现在可以正常工作.
To fix this, I downloaded a copy of xml.xsd, and add it explicitly using the settings.Schemas.Add
method: the validation now works correctly when the machine is not connected to the internet.
但是,当机器连接到 Internet 时,我现在收到一条错误消息,指出 全局属性 'http://www.w3.org/XML/1998/namespace:lang' 已被声明.
.
However when the machine is connected to the internet, I now get an error saying that The global attribute 'http://www.w3.org/XML/1998/namespace:lang' has already been declared.
.
所以显然我需要明确添加它,或者我不需要,这取决于机器是否能够从互联网上静默下载它(或者甚至可能以前能够下载它,并将它缓存在某个地方).
So apparently I either need to add it explicitly, or I don't, depending on whether the machine is able to silently download it from the internet (or even perhaps has previously been able to download it, and has it cached somewhere).
所以,它是如果我这样做该死,如果我不这样做该死".我是否需要以一种方式尝试,捕获异常,然后以另一种方式尝试?还是有更优雅的解决方案?
So, it's "damned if I do and damned if I don't". Do I need to try it one way, catch the exception and then try it the other way? Or is there a more elegant solution?
推荐答案
我们看不到您的代码,但是在许多实现中,这是通过将 .xsd 的请求重定向到本地来处理的使用目录解析器进行复制.有一个属性 XmlReaderSettings.XmlResolver可用于此.请参阅 XMLCatalog.net 了解您可以使用的 Apache 许可实现.
We can't see your code, but In many implementations this is handled by redirecting the request for the .xsd to the local copy using a catalog resolver. There is a property XmlReaderSettings.XmlResolver that can be used for this. See XMLCatalog.net for an Apache-licensed implementation you can use.
这样做的副作用是您可以将所有模式缓存在本地.这一点尤其重要,因为 W3C 会阻止对其站点的过度读取,并且您的代码(或更糟糕的是,您客户的代码)会随机开始失败.
A side-effect of this is that you can keep all schemas cached locally. This is especially important since W3C will block excessive reads to their site and randomly your code (or worse, your customer's code) will begin to fail.
这篇关于使用 .NET 针对架构验证 XML的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!